PHP扩展怎样实现单例模式_PHP扩展单例模式实现思路【解析】

看不見的法師
发布: 2025-12-21 23:41:23
原创
873人浏览过
PHP扩展中实现单例有四种方式:一、模块全局静态变量在MINIT初始化并延迟构造;二、利用EG(registry)运行时查存;三、自定义create_object handler复用zval;四、ZTS下用TSRM线程局部存储。

php扩展怎样实现单例模式_php扩展单例模式实现思路【解析】

在PHP扩展开发中,若需确保某个资源或对象在整个PHP生命周期内仅被初始化一次,可通过C语言层面的静态变量与Zend引擎的模块生命周期管理来实现单例语义。以下是几种可行的实现路径:

一、使用模块全局静态变量

利用PHP扩展的MINIT(模块初始化)阶段,在扩展全局结构体中声明静态指针,指向唯一实例;后续每次调用获取实例函数时,仅在首次为NULL时执行构造逻辑。

1、在扩展头文件中定义全局结构体成员:zend_object_value *g_singleton_instance = NULL;

2、在MINIT函数中初始化该指针为NULL:g_singleton_instance = NULL;

立即学习PHP免费学习笔记(深入)”;

3、实现ZEND_FUNCTION(get_singleton)函数,在其中判断指针是否为空:if (g_singleton_instance == NULL) { /* 执行对象创建与注册 */ }

4、使用zend_register_resource或直接分配zend_object_value并绑定自定义handlers。

二、基于EG(scope)或CG()宏的运行时单例控制

借助Zend引擎提供的全局执行上下文宏,在请求开始(RINIT)或函数调用时检查当前是否存在已注册的单例资源标识符,避免重复初始化。

1、在RINIT中不主动创建实例,仅预留资源槽位:zend_hash_init(&EG(registry), 4, NULL, ZVAL_PTR_DTOR, 0);

2、在获取函数中尝试从EG(registry)查找键名为"my_singleton"的zval:if (zend_hash_find(&EG(registry), "my_singleton", sizeof("my_singleton"), (void**)&zv) == SUCCESS) { /* 返回已有值 */ }

3、若未找到,则手动构造对象并插入registry:zend_hash_update(&EG(registry), "my_singleton", sizeof("my_singleton"), &zv, sizeof(zval), NULL);

三、通过类句柄+静态属性模拟单例

在PHP用户空间定义final类并私有化构造方法,同时在扩展中拦截该类的实例化过程,强制重用同一zval地址。

1、在扩展中注册一个自定义的zend_class_entry,并设置其create_object handler为定制函数:ce->create_object = my_singleton_create_object;

2、在my_singleton_create_object函数中,检测全局静态zval是否已初始化:if (Z_TYPE_P(g_cached_obj_zval) != IS_NULL) { return g_cached_obj_zval; }

3、否则调用object_and_properties_init初始化新对象,并将地址保存至g_cached_obj_zval。

4、确保该zval在MSHUTDOWN阶段被正确释放:zval_dtor(g_cached_obj_zval);

四、使用TSRM线程安全存储隔离单例

当扩展运行于ZTS(Zend Thread Safety)模式下,需为每个线程维护独立的单例副本,此时应采用ts_allocate_id分配线程局部存储键。

1、声明ts_rsrc_id变量:static ts_rsrc_id singleton_globals_id;

2、在PHP_MINIT_FUNCTION中调用ts_allocate_id分配ID:ts_allocate_id(&singleton_globals_id, sizeof(my_singleton_globals), NULL, NULL);

3、在获取函数中通过ts_resource获取当前线程专属结构体指针:my_singleton_globals *g = (my_singleton_globals*)ts_resource(singleton_globals_id);

4、检查g->instance是否为NULL,若为空则执行初始化并赋值。

以上就是PHP扩展怎样实现单例模式_PHP扩展单例模式实现思路【解析】的详细内容,更多请关注php中文网其它相关文章!

PHP速学教程(入门到精通)
PHP速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号