php扩展开发 ini配置项定义
扩展 jlog
首先、在 php_jlog.h
文件中添加如下代码。使用扩展工具生成的扩展框架中包含下面的代码,只是默认情况下是注释的,可以把注释打开然后修改。
zend_begin_module_globals(jlog)
zend_bool enable_thread;
zend_end_module_globals(jlog)
然后、在jlog.c
文件中添加如下代码。
zend_declare_module_globals(jlog);
php_ini_begin()
std_php_ini_entry("jlog.enable_thread", "1", php_ini_system, onupdatebool, enable_thread, zend_jlog_globals, jlog_globals)
php_ini_end()
php_ginit_function(jlog)
{
jlog_g(enable_thread) = 1;
}
最后需要在php_minit_function(jlog)
中注册全局变量
php_minit_function(jlog)
{
register_ini_entries(); // 注册全局变量入口
server_start = 0;
if(!queue_init()) {
php_error(e_error,"队列初始化失败\n");
}
return success;
}
// 在生命周期最后销毁这些全局变量
php_mshutdown_function(jlog)
{
unregister_ini_entries(); // 销毁
if(server_start == 1) {
server_start = 0;
if(jlog_g(enable_thread)) {
while (!checkqueueempty() || !idle) {}
pthread_cancel(tid);
pthread_join(tid, null);
}
}
free(jlog_queue);
return success;
}
到此,基本流程就完成了。但是我们注意到在上面新增了php_ginit_function(jlog)
。 这是用来初始化全局变量的。但是默认情况下这是不会执行的。需要我们来手动指定其调用。
在jlog.c
默认的有个变量
zend_module_entry pen_module_entry = {
standard_module_header,
"pen",
pen_functions,
php_minit(pen),
php_mshutdown(pen),
php_rinit(pen), /* replace with null if there's nothing to do at request start */
php_rshutdown(pen), /* replace with null if there's nothing to do at request end */
php_minfo(pen),
php_pen_version,
standard_module_properties
};
我们需要对这个变量的值进行修改,因为standard_module_properties
宏定义如下
#define standard_module_properties \
no_module_globals, null, standard_module_properties_ex
// 其中有个宏 no_module_globals 由名字就可以知道禁止了全局变量
#define no_module_globals 0, null, null, null
所以我们需要将jlog.c
中的变量进行修改
zend_module_entry jlog_module_entry = {
standard_module_header,
"jlog",
jlog_functions,
php_minit(jlog),
php_mshutdown(jlog),
php_rinit(jlog), /* replace with null if there's nothing to do at request start */
php_rshutdown(jlog), /* replace with null if there's nothing to do at request end */
php_minfo(jlog),
php_jlog_version,
php_module_globals(jlog),
php_ginit(jlog), // php_ginit_function(jlog) 的调用
null,
null,
standard_module_properties_ex
};
上面的变量是由zend_module_entry
定义,而zend_module_entry
结构体如下
typedef struct _zend_module_entry zend_module_entry;
struct _zend_module_entry {
unsigned short size;
unsigned int zend_api;
unsigned char zend_debug;
unsigned char zts;
const struct _zend_ini_entry *ini_entry;
const struct _zend_module_dep *deps;
const char *name;
const 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);
const 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;
const char *build_id;
};
这里定义了一个php
扩展模块的入口,里面定义了一个模块整个生命周期所需要的信息。
到此为止,已经是一个完整的扩展了。但是,还有一个问题,这个扩展只是对于zts版本的php有效。对于nts版本的在编译的时候会报错。原因就是下面这段代码
php_ginit_function(jlog)
{
jlog_g(enable_thread) = 1;
}
按照php_jlog.h 中定义的
#ifdef zts
#define jlog_g(v) tsrmg(jlog_globals_id, zend_jlog_globals *, v)
extern int jlog_globals_id;
#else
#define jlog_g(v) (jlog_globals.v)
extern zend_jlog_globals jlog_globals;
#endif
在nts版本中,jlog_g(v)
的定义是jlog_globals.v
。 在php_ginit_funxtion(jlog)
函数中直接使用宏jlog_g(enable_thread)
在编译过程中是有问题的。此时的jlog_globals
是一个指针变量,所以 jlog_globals.v 是会报错的。因此将php_ginit_function(jlog)
修改如下
php_ginit_function(jlog)
{
jlog_globals->enable_thread = 1;
}
则编译的时候则不会报错。
至于为什么nts版本会出现这种情况,现在还没有找到具体原因,等后续研究找到原因后再回来补上,先做个todo
转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处
本文地址:
相关文章
如何使用 clion 开发调试 php 扩展
发布时间:2021/07/02 浏览次数:287 分类:php
-
php 扩展的创建这里就不再赘述,使用ext_skel 生成一个框架,然后编辑相应的文件,编译安装,最后在php.ini 配置文件中加入生成的扩展 例如 my_ext.so
php扩展开发之最详细的return_stringl讲解
发布时间:2021/06/15 浏览次数:226 分类:php
-
本篇主要介绍在php扩展开发的过程中肯定会用到的一个宏 return_stringl 。
php内核开发,接收用户传入的参数
发布时间:2021/06/10 浏览次数:214 分类:php
-
在内核开发中,在接收用户传入的参数的过程中,可以使用 zend_parse_parameters()函数。