php扩展开发 ini配置项定义-ag捕鱼王app官网

php扩展开发 ini配置项定义

作者:迹忆客 最近更新:2022/12/26 浏览次数:

扩展 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

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便
网站地图