zendAPI 项目不供应任何底层的功能,只是封装了 zend engine 供应的功能,对上供应一个易用的编程接口。这篇文章中,我们将先容 C++ 天下与 C 天下交汇的地方,在这里也是 zendAPI 的接口与 zend engine 进行整合的地方,非常主要。
每一个 PHP 扩展必须有一个描述工具,在 zendAPI 中我们 zapi::lang::Extension 类紧张的浸染紧张完成这个功能。现在我们来看一个最大略的 zendAPI 项目的入口文件长什么样子:
#include \"大众zapi/ZendApi.h\"大众extern \公众C\"大众 { ZAPI_DECL_EXPORT void get_module() { static zapi::lang::Extension hellozapi(\公众hellozapi\公众, \"大众1.0\"大众); return hellozapi;}}
怎么样很大略吧,一个空的 PHP 扩展就完成了,现在我们就详细阐明下每行的浸染。
#include \"大众zapi/ZendApi.h\"大众
在开拓基于 zendAPI 的项目时候,我们只须要包含这个头文件就可以了,在这个头文件中,我们会引入 zendAPI 日常开拓须要的必要的头文件,您不用自己一个一个自己去引入。
extern \"大众C\公众{}
在 CPP 代码与 C 代码进行连接的时候我们一样平常会加上 extern wrapper, 由于如果不加的话 CPP 编译器会对函数名称进行 name mangling,这个会导致连接的时候提示符号不存在的缺点。
ZAPI_DECL_EXPORT void get_module();
ZAPI_DECL_EXPORT 表示我们扩展导出符号 get_module 给其他库利用。函数 get_module 这个函数非常主要,他是 zendAPI 与 zend engine 进行集成的入口,我们必须在这个函数中设置好我们扩展的统统,然后将扩展描述工具的指针返回。
在这里我先大略描述下 PHP 加载扩展这部分的过程:
在 PHP 初始化的过程中调用的函数有:(这里我们以 cli SAPI 为例进行解释)
php_cli_startup
php_module_startup
php_ini_register_extensions
zend_llist_apply
php_load_extension
get_module = (zend_module_entry ()(void)) DL_FETCH_SYMBOL(handle, “_get_module”);
调用 get_module,获取zend_module_entry 工具指针
大略来说我们可以这样理解,在 PHP 模块初始化的时候,PHP 会去读取我们在 php.ini 文件中注册的扩展, 比如咱们的 hellozapi 就在 php.ini 注册了一行 extension=hellozapi.so。如果干系的扩展文件存在,PHP 利用 dlopen 平台接口进行动态加载,成功的话, 获取 _get_module 符号,然后进行调用,终极获取一个 zend_module_entry 指针。
static zapi::lang::Extension hellozapi(\公众hellozapi\公众, \公众1.0\"大众);
这行代码实例化一个扩展工具,第一个参数是咱们的扩展的名称,一样平常须要跟在 CMake 脚本中定义的项目名字保持同等,第二个参数指定扩展的版本号,这里我们定义为 1.0,这些信息我们都可以在 PHP 脚本中通过反射技能获取同时也会涌如今 phpinfo() 函数的输出中。
特殊提醒:这里的 static 关键字不能去掉,去掉了我们就返回了一个悬空指针。(dangle pointer)
return hellozapi;
新手可能会有疑问,我们的 get_module 明明是返回一个 void ,而我们这里返回 zapi::lang::Extension 工具怎么也可以啊 ?事理很大略,由于我们的 zapi::lang::Extension 定义了一个转换运算符,C++ 编译器会自动进行类型转换。
到这里,我们这个空的 PHP 扩展就完成了,怎么样,大略吧?安歇一下我们连续。
#文章利用的编程文档的引用连接
ZAPI_DECL_EXPORT
http://zendapi.org/api/file_compiler_detection_8h.html#1a6483198f166d8060fb07d99604ef1cfe
zapi::lang::Extension
http://zendapi.org/api/classzapi_1_1lang_1_1_extension.html
更多精彩的教程您可以访问我们的手册:www.zendapi.org/manual