一直想切入php真正的底层开发,今天终于迈出了重要的一步。
首先需要明白一点,c开发的扩展注册到php内是通过
zend_module_entry
结构
php已经提供了一个快速创建一个扩展的骨架方法,在php的源码下ext目录下 ext_skel该为php提供的快速创建骨架的脚本文件,操作方法:
./ext_skel -extname=zeeyer
执行后会在ext目录下自动创建zeeyer扩展骨架
zeeyer扩展目录下有几个文件是很重要的
config.m4
php_zeeyer.h
zeeyer.c
config.m4文件中
PHP_NEW_EXTENSION(extname,source[ ,shared [,sapi_class [,extra-cflags [,cxx [, zend_ext]]]]]);
注册一个扩展,列举扩展全部的*.c源文件,确定该扩展为动态库还是静态库,每个扩展的config.m4中都需要通过这个宏完成扩展的编译配置
开发扩展这个是必须要用到的,所以就先了解下这个,其余自行了解
接下来,我们还得了解下php的生命周期,因为在php的生命周期不同阶段中有不同的钩子函数,而我们就是利用钩子函数来将我们开发的扩展注册到php中
php的生命周期分为:
模块初始阶段(module startup):module startup
请求初始阶段(request startup):request startup
执行脚本阶段(execute script):request shutdown
请求关闭阶段(request shutdown):post deactivate
模块关闭阶段(module shutdown):module shutdown
主要说明下第一个钩子函数,在module startup该钩子函数在扩展中使用ZEND_MINIT_FUNCTION()宏定义这个函数,一般内部类的注册在该处执行。其余的钩子函数最好去了解下php底层运行机制。
接下来就具体的说明下扩展的函数定义以及类定义:
函数:
PHP_FUNCTION(comfirm_zeeyer_compiled)
通过使用该宏完成函数的定义,然后存储到一个数组
constzend_function_entryzeeyer_functions[] = {
PHP_FE(confirm_zeeyer_compiled,NULL)/* For testing, remove later. */
PHP_FE_END/* Must be the last line in zeeyer_functions[] */
};
最后,完成函数注册
zend_module_entryzeeyer_module_entry = {
STANDARD_MODULE_HEADER,
"zeeyer",
zeeyer_functions,
PHP_MINIT(zeeyer),
PHP_MSHUTDOWN(zeeyer),
PHP_RINIT(zeeyer),/* Replace with NULL if there's nothing to do at request start */
PHP_RSHUTDOWN(zeeyer),/* Replace with NULL if there's nothing to do at request end */
PHP_MINFO(zeeyer),
PHP_ZEEYER_VERSION,
STANDARD_MODULE_PROPERTIES
};
类:
通过zend_class_entry结构定义一个存储类的指针
ZEND_METHOD()
定义类中的方法,然后存储到数组中
constzend_function_entryzeeyer_request_methods[] = {
PHP_ME(Zeeyer_Request,start,NULL,ZEND_ACC_PUBLIC)
PHP_FE_END
};
其次
ZEEYER_MINIT_FUNCTION(Request)
{
zend_class_entryzeeyer_request;
INIT_CLASS_ENTRY(zeeyer_request,"Zeeyer_Request",zeeyer_request_methods);
zeeyer_request_ce = zend_register_internal_class(&zeeyer_request);
returnSUCCESS;
}
最后回到刚才php生命周期中说过的,类需要在模块初始化阶段中进行注册,通过
ZEND_MODULE_STARTUP_N(Zeeyer_Request)(INIT_FUNC_ARGS_PASSTHRU)
注册
zeeyer_request.h宏代码段:
#ifndefZEEYER_REQUEST_H
#defineZEEYER_REQUEST_H
externzend_class_entry*zeeyer_request_ce;
ZEND_METHOD(Zeeyer_Request,start);
ZEEYER_MINIT_FUNCTION(Request);
#endif
领取专属 10元无门槛券
私享最新 技术干货