PHP扩展中实现单例有四种方式:一、模块全局静态变量在MINIT初始化并延迟构造;二、利用EG(registry)运行时查存;三、自定义create_object handler复用zval;四、ZTS下用TSRM线程局部存储。
在PHP扩展开发中,若需确保某个资源或对象在整个PHP生命周期内仅被初始化一次,可通过C语言层面的静态变量与Zend引擎的模块生命周期管理来实现单例语义。以下是几种可行的实现路径:
利用PHP扩展的MINIT(模块初始化)阶段,在扩展全局结构体中声明静态指针,指向唯一实例;后续每次调用获取实例函数时,仅在首次为NULL时执行构造逻辑。
1、在扩展头文件中定义全局结构体成员:zend_object_value *g_singleton_instance = NULL;
2、在MINIT函数中初始化该指针为NULL:g_singleton_instance = NULL;
3、实现ZEND_FUNCTION(get_singleton)函数,在其中判断指针是否为空:if (g_singleton_instance == NULL) { /* 执行对象创建与注册 */ }
4、使用zend_register_resource或直接分配zend_object_value并绑定自定义handlers。
借助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);
当扩展运行于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->instan
ce是否为NULL,若为空则执行初始化并赋值。
# php
# c语言
# php扩展
# Static
# NULL
# if
# 标识符
# 结构体
# void
# 指针
# 线程
# Thread
# 对象
# 自定义
# 首次
# 句柄
# 已有
# 并将
# 几种
# 四种
# 可通过
# 来实现
# 时应
相关文章:
,想在网上投简历,哪几个网站比较好?
如何注册花生壳免费域名并搭建个人网站?
如何在IIS服务器上快速部署高效网站?
PHP 500报错的快速解决方法
如何做静态网页,sublimetext3.0制作静态网页?
如何批量查询域名的建站时间记录?
山东云建站价格为何差异显著?
建站之星会员如何解锁更多建站功能?
网站视频怎么制作,哪个网站可以免费收看好莱坞经典大片?
php8.4新语法match怎么用_php8.4match表达式替代switch【方法】
如何登录建站主机?访问步骤全解析
智能起名网站制作软件有哪些,制作logo的软件?
学校免费自助建站系统:智能生成+拖拽设计+多端适配
制作网站的公司有哪些,做一个公司网站要多少钱?
黑客入侵网站服务器的常见手法有哪些?
如何获取上海专业网站定制建站电话?
建站之星如何实现PC+手机+微信网站五合一建站?
如何选择长沙网站建站模板?H5响应式与品牌定制哪个更优?
标准网站视频模板制作软件,现在有哪个网站的视频编辑素材最齐全的,背景音乐、音效等?
如何在阿里云服务器自主搭建网站?
c++怎么编写动态链接库dll_c++ __declspec(dllexport)导出与调用【方法】
*服务器网站为何频现安全漏洞?
最好的网站制作公司,网购哪个网站口碑最好,推荐几个?谢谢?
制作网站的软件下载免费,今日头条开宝箱老是需要下载怎么回事?
制作销售网站教学视频,销售网站有哪些?
广德云建站网站建设方案与建站流程优化指南
免费制作小说封面的网站有哪些,怎么接网站批量的封面单?
C#如何序列化对象为XML XmlSerializer用法
宠物网站制作html代码,有没有专门介绍宠物如何养的网站啊?
,sp开头的版面叫什么?
手机钓鱼网站怎么制作视频,怎样拦截钓鱼网站。怎么办?
怀化网站制作公司,怀化新生儿上户网上办理流程?
如何在香港服务器上快速搭建免备案网站?
SAX解析器是什么,它与DOM在处理大型XML文件时有何不同?
品牌网站制作公司有哪些,买正品品牌一般去哪个网站买?
长春网站建设制作公司,长春的网络公司怎么样主要是能做网站的?
东莞专业网站制作公司有哪些,东莞招聘网站哪个好?
导航网站建站方案与优化指南:一站式高效搭建技巧解析
实例解析angularjs的filter过滤器
企业宣传片制作网站有哪些,传媒公司怎么找企业宣传片项目?
企业微网站怎么做,公司网站和公众号有什么区别?
阿里云网站搭建费用解析:服务器价格与建站成本优化指南
如何制作一个表白网站视频,关于勇敢表白的小标题?
小视频制作网站有哪些,有什么看国内小视频的网站,求推荐?
音乐网站服务器如何优化API响应速度?
建站主机数据库如何配置才能提升网站性能?
如何快速生成橙子建站落地页链接?
宝塔建站无法访问?如何排查配置与端口问题?
香港服务器建站指南:免备案优势与SEO优化技巧全解析
关于BootStrap modal 在IOS9中不能弹出的解决方法(IOS 9 bootstrap modal ios 9 noticework)
*请认真填写需求信息,我们会在24小时内与您取得联系。