强制模块依赖

在php 5.1中, 扩展之间的内部依赖是可以强制性的. 由于扩展可以静态构建到php中, 也可以构建为共享对象动态加载, 因此强制依赖需要在两个地方实现.

配置时模块依赖

第一个位置是你在本章课程中刚刚看到的config.m4文件中. 你可以使用PHP_ADD_EXTENSION_DEP(extname, depname[ , optional])宏标识extname这个扩展依赖于depname这个扩展. 当extname以静态方式构建到php中时, ./configure脚本将使用这一行代码确认depname必须首先初始化. optional参数是一个标记, 用来标识depname如果也是静态构建的, 应该在extname之前加载, 不过它并不是必须的依赖.

这个宏的一个使用示例是pdo驱动, 比如pdo_mysql是可预知依赖于pdo扩展的:

  1. ifdef([PHP_ADD_EXTENDION_DEP],
  2. [
  3. PHP_ADD_EXTENSION_DEP(pdo_mysql, pdo)
  4. ])

要注意PHP_ADD_EXTENSION_DEP()宏被包裹到一个ifdef()结构中. 这是因为pdo和它的驱动在编译大于或等于5.0版本的php时都是存在的, 然而PHP_ADD_EXTENSION_DEP()宏是直到5.1.0版本才出现的.

运行时模块依赖

另外一个你需要注册依赖的地方是zend_module_entry结构体中. 考虑下面第5章中你定义的zend_module_entry结构体:

  1. zend_module_entry sample_module_entry = {
  2. #if ZEND_MODULE_API_NO >= 20010901
  3. STANDARD_MODULE_HEADER,
  4. #endif
  5. PHP_SAMPLE_EXTNAME,
  6. php_sample_functions,
  7. NULL, /* MINIT */
  8. NULL, /* MSHUTDOWN */
  9. NULL, /* RINIT */
  10. NULL, /* RSHUTDOWN */
  11. NULL, /* MINFO */
  12. #if ZEND_MODULE_API_NO >= 20010901
  13. PHP_SAMPLE_EXTVER,
  14. #endif
  15. STANDARD_MODULE_PROPERTIES
  16. };

增加运行时模块依赖信息就需要对STANDARD_MOUDLE_HEADER部分进行一些小修改:

  1. zend_module_entry sample_module_entry = {
  2. #if ZEND_MODULE_API_NO >= 220050617
  3. STANDARD_MODULE_HEADER_EX, NULL,
  4. php_sample_deps,
  5. #elif ZEND_MODULE_API_NO >= 20010901
  6. STANDARD_MODULE_HEADER,
  7. #endif
  8. PHP_SAMPLE_EXTNAME,
  9. php_sample_functions,
  10. NULL, /* MINIT */
  11. NULL, /* MSHUTDOWN */
  12. NULL, /* RINIT */
  13. NULL, /* RSHUTDOWN */
  14. NULL, /* MINFO */
  15. #if ZEND_MODULE_API_NO >= 20010901
  16. PHP_SAMPLE_EXTVER,
  17. #endif
  18. STANDARD_MODULE_PROPERTIES
  19. };

现在, 如果ZEND_MODULE_API_NO高于php 5.1.0 beta发布版, 则STANDARD_MODULE_HEADER(译注: 这里原著笔误为STANDARD_MODULE_PROPERTIES)将被替换为略微复杂的结构, 它将包含一个指向模块依赖信息的引用.

这个目标结构体可以在你的zend_module_entry结构体上面定义如下:

  1. #if ZEND_MODULE_API_NO >= 220050617
  2. static zend_module_dep php_sample_deps[] = {
  3. ZEND_MODULE_REQUIRED("zlib")
  4. {NULL,NULL,NULL}
  5. };
  6. #endif

和zend_function_entry向量类似, 这个列表可以有多项依赖, 按照顺序进行检查. 如果尝试加载某个依赖模块未满足, Zend将会中断加载, 报告不满足依赖的名字, 这样, 终端用户就可以通过首先加载其他模块来解决问题.