IT技术博客大学习 共学习 共进步

保证PHP扩展的依赖关系

风雪之隅 2009-10-29 22:49:22 浏览 2,802 次

cyj网友提到, 如果俩个PHP扩展模块之间有互相依赖关系, 那么该如何保证正确的加载顺序呢?

也就是说, 如何保证模块的依赖关系?

关于这个问题, 可以从如下俩点入手展开:

1. 扩展的加载顺序是和它出现在配置文件中的先后顺序相关的, 也就是说, 如果在配置文件中的顺序如下,

以下是代码片段:
extension=mysql.so
extension=pdo.so
    

那么, mysql扩展就会比pdo扩展先载入.

同理,对于单独的配置文件,则和这个文件的载入顺序相关. 一般来说,这个时候和这个文件的命名相关.

2. 那么如果顺序出错, 我们又要怎么保证正确的加载, 或者告诉Zend此时出错了呢?

回忆, 我们在写扩展的时候, 都会申明一个zend_module_entry结构的扩展说明模块, 这个结构用来告诉Zend所有和当前模块相关的, Zend关心的信息, 也就是在这里, 我们可以申明我们的模块所依赖的模块, 这样当依赖关系出错的时候Zend就会报错, 给出详细的出错信息, 并停止运行.

以下是代码片段:
struct _zend_module_entry {
    unsigned short size;
    unsigned int zend_api;
    unsigned char zend_debug;
    unsigned char zts;
    struct _zend_ini_entry *ini_entry;
    struct _zend_module_dep *deps;  //关键属性
    char *name;
    struct _zend_function_entry *functions;
    int (*module_startup_func)(INIT_FUNC_ARGS);
    int (*module_shutdown_func)(SHUTDOWN_FUNC_ARGS);
    int (*request_startup_func)(INIT_FUNC_ARGS);
    int (*request_shutdown_func)(SHUTDOWN_FUNC_ARGS);
    void (*info_func)(ZEND_MODULE_INFO_FUNC_ARGS);
    char *version;
    size_t globals_size;
#ifdef ZTS
    ts_rsrc_id* globals_id_ptr;
#else
    void* globals_ptr;
#endif
    void (*globals_ctor)(void *global TSRMLS_DC);
    void (*globals_dtor)(void *global TSRMLS_DC);
    int (*post_deactivate_func)(void);
    int module_started;
    unsigned char type;
    void *handle;
    int module_number;
};
   

第5个属性, zend_module_dep是一个接受zend_module_dep结构数组的指针, 用来指出当前模块所以来的所有模块, 而zend_module_dep的结构如下:

以下是代码片段:
struct _zend_module_dep {
    char *name;         /* module name */
    char *rel;          /* version relationship: NULL (exists), lt|le|eq|ge|gt (to given version) */
    char *version;      /* version */
    unsigned char type; /* dependency type */
};
  

但, 很PHP特色的, 我们不需要知道详细的这个结构细节, 也不需要去和这个结构直接接触, 我们可以使用PHP提供的宏:GET_MOD_REQUIRE来完成zend_module_dep的填写, 比如在pdo_mysql中:

以下是代码片段:
static zend_module_dep pdo_mysql_deps[] = {
    ZEND_MOD_REQUIRED("pdo")
    {NULL, NULL, NULL}
};

申明了, pdo_mysql必须依赖于pdo扩展模块.

然后,把这个数组指针填入pdo_mysql_module_entry中相应字段即可完成我们的目标~

建议继续学习

  1. chrome扩展应用开发教程之开发chrome应用基础 (阅读 5,604)
  2. PHP内核介绍及扩展开发指南―高级主题 (阅读 4,584)
  3. chrome扩展应用开发教程之调试和打包上线 (阅读 4,426)
  4. 深入理解PHP原理之扩展载入过程 (阅读 4,384)
  5. Mediawiki扩展编写实战 (阅读 4,383)
  6. 编写python的C语言扩展 (阅读 4,325)
  7. PHP内核介绍及扩展开发指南―类和对象 (阅读 4,006)
  8. 用C/C++扩展你的PHP (阅读 3,764)
  9. PHP7扩展开发之hello word (阅读 3,562)
  10. PHP扩展开发:第一个扩展 (阅读 3,542)