返回顶部
首页 > 资讯 > 后端开发 > PHP编程 >PHP扩展开发 ini配置项定义
  • 743
分享到

PHP扩展开发 ini配置项定义

2024-02-27 19:02:07 743人浏览 八月长安
摘要

扩展 jlog 首先、在 PHP_jlog.h 文件中添加如下代码。使用扩展工具生成的扩展框架中包含下面的代码,只是默认情况下是注释的,可以把注释打开然后修改。 ZEND_BEGIN_MODULE

扩展 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),        
    PHP_RSHUTDOWN(pen),    
    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),        
        PHP_RSHUTDOWN(jlog),    
        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

--结束END--

本文标题: PHP扩展开发 ini配置项定义

本文链接: https://lsjlt.com/news/568933.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作