【PECL】在扩展中实现 autoload

【PECL】在扩展中实现 autoload

  • 摘要
  • PHP代码想这么写
  • C 代码这么实现

摘要

php-8.3.x 用扩展写个框架。想实现类管理器,自动加载,上代码:

PHP代码想这么写

$ws = new \Ziima\Applet();
$ws->import('Ziima', '../base/core');
$ws->runAutoload();$t = new \Ziima\Template\Context();
print_r($t);

C 代码这么实现

没有文档,硬翻源代码一点点抠出来这么个思路,能用。

ZEND_METHOD(Ziima_Applet, runAutoload) {zval *this       = getThis();zend_string *req = NULL;ZEND_PARSE_PARAMETERS_START(0, 1)Z_PARAM_OPTIONALZ_PARAM_STR(req)ZEND_PARSE_PARAMETERS_END();//[1] 没有参数 , 或者 this._auto 未设置,判断是PHP调用 runAutoload 来注册zval *_auto = zend_read_property(ce_Ziima_Applet, Z_OBJ_P(this), ZEND_STRL("_auto"), true, NULL);if (_auto == NULL || Z_TYPE_P(_auto) != IS_OBJECT) {zval           cu, par_r;zend_function *fn = zend_hash_str_find_ptr_lc(&Z_OBJCE_P(this)->function_table, ZEND_STRL("runAutoload"));zend_create_closure(&cu, fn, ce_Ziima_Applet, ce_Ziima_Applet, this);zend_fcall_info fci;fci.size         = sizeof(zend_fcall_info);fci.object       = NULL;fci.named_params = NULL;fci.retval       = &par_r;fci.param_count  = 3;fci.params       = ecalloc(sizeof(zval), 3);ZVAL_COPY_VALUE(fci.params, &cu);ZVAL_TRUE(fci.params + 1);ZVAL_TRUE(fci.params + 2);ZVAL_STRING(&fci.function_name, "spl_autoload_register");if (zend_call_function(&fci, NULL) != SUCCESS) {zval_delref_p(&cu);RETURN_FALSE;}if (Z_TYPE(par_r) != IS_TRUE) {zval_delref_p(&cu);RETURN_FALSE;}zend_update_property(ce_Ziima_Applet, Z_OBJ_P(this), ZEND_STRL("_auto"), &cu);RETURN_TRUE;}// [2] 有参数进来,则认为是被 spl_autoload_register 调用的if (req == NULL) {RETURN_FALSE;}zval *_vendor = zend_read_property(ce_Ziima_Applet, Z_OBJ_P(this), ZEND_STRL("_vendor"), true, NULL);if (_vendor == NULL || Z_TYPE_P(_vendor) != IS_ARRAY)RETURN_FALSE;if (zend_array_count(Z_ARR_P(_vendor)) < 1)RETURN_FALSE;// [3] 类加载器只能处理有命名空间的if (!nstr_contains(req->val, req->len, '\\'))RETURN_FALSE;vector_object *vreq   = vector_split_ex(req->val, req->len, '\\', VCONF_AUTO_TRIM | VCONF_DENY_EMPTY);vector_item   *ve     = vector_first(vreq);zend_string   *ns_req = zend_string_init(ve->key.val, ve->key.len, false);zend_string   *dp_req = NULL;zend_long      h      = 0;zend_string   *k      = NULL;zval          *v      = NULL;// [4] 找登记路径ZEND_HASH_MAP_FOREACH_KEY_VAL(Z_ARR_P(_vendor), h, k, v)if (k->len != ns_req->len)continue;if (strncasecmp(k->val, ns_req->val, ns_req->len) == 0) {dp_req = zend_string_dup(Z_STR_P(v), false);break;}ZEND_HASH_FOREACH_END();if (dp_req == NULL) {vector_destroy(vreq);zend_string_release(ns_req);RETURN_FALSE;}// [5] 拼路径buf_string tmp;bstr_init(&tmp, dp_req->len + req->len + 64);bstr_append(&tmp, dp_req->val);if (tmp.val[dp_req->len - 1] == '/') {tmp.val[dp_req->len - 1] = 0;tmp.len--;}VECTOR_FOREACH_BEGIN(vreq, h, ve)if (h == 1)continue;bstr_append_char(&tmp, '/');bstr_append_ex(&tmp, ve->key.val, ve->key.len);VECTOR_FOREACH_END();vector_destroy(vreq);bstr_append(&tmp, ".php");// [6] 查文件zend_string_release(ns_req);zend_string_release(dp_req);if (access(tmp.val, F_OK) != 0) {bstr_free(&tmp);RETURN_FALSE;}// kdebug("load %s from %s", ns_req->val, tmp.val);// [7] 用 eval + include_once 包含bstr_append(&tmp, "');");const char *ps = "include_once('";uint32_t    ls = strlen(ps);memmove(tmp.val + ls, tmp.val, tmp.len);memcpy(tmp.val, ps, ls);if (zend_eval_string(tmp.val, NULL, "ziima_autoload_script") != SUCCESS) {bstr_free(&tmp);RETURN_FALSE;}bstr_free(&tmp);RETURN_TRUE;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/22486.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

调用万维易源API生成AI艺术二维码

目录 1. 作者介绍2. 艺术二维码2.1 艺术二维码的作用2.2 艺术二维码的应用场景2.3调用万维易源API生成AI艺术二维码 3. 实验过程3.1算法流程3.2完整代码3.3测试结果 1. 作者介绍 韩阳&#xff0c;男&#xff0c;西安工程大学电子信息学院&#xff0c;2023级研究生 研究方向&am…

C++ 并发编程指南(13)线程池原理与实践 | 13.2、关键组件实现

文章目录 一、关键组件实现1、任务队列 前言&#xff1a; 一、关键组件实现 1、任务队列 任务队列的主要功能是保存要执行的任务&#xff0c;有下面这些需要解决的问题 问题一&#xff1a;如何保证任务的通用性&#xff1f; 因为任务队列要有通用性&#xff0c;所以规定任务队…

力扣2653.滑动子数组的美丽值

力扣2653.滑动子数组的美丽值 计数排序&#xff1a;数值作为下标 记录个数 求第x小的数 &#xff1a; 暴力枚举负数 直到找到第x个负数 class Solution {public:vector<int> getSubarrayBeauty(vector<int>& nums, int k, int x) {const int BIAS 50;int c…

两种参与茶树O-甲基化儿茶素生物合成的O-甲基转移酶的特征分析-文献精读20

Characterization of two O-methyltransferases involved in the biosynthesis of O-methylated catechins in tea plant 两种参与茶树O-甲基化儿茶素生物合成的O-甲基转移酶的特征分析 茶树三维基因组-文献精读19 比较转录组分析揭示了116种山茶属(Camellia)植物的深层系统…

设计模式23——状态模式

写文章的初心主要是用来帮助自己快速的回忆这个模式该怎么用&#xff0c;主要是下面的UML图可以起到大作用&#xff0c;在你学习过一遍以后可能会遗忘&#xff0c;忘记了不要紧&#xff0c;只要看一眼UML图就能想起来了。同时也请大家多多指教。 状态模式&#xff08;State&am…

固件windows升级

升级主机驱动截图及描述补充&#xff1a; 由于卡上的固件需要更换版本&#xff0c;所以总共下载四个东西&#xff1a;固件、驱动、转译工具及Cli命令。&#xff08;转译工具是为了解密&#xff0c;如果固件上有加密日志&#xff0c;要进行查看操作的时候&#xff09; 通过命令…

《幸福》期刊杂志投稿发表

《幸福》杂志是由国家新闻出版总署批准&#xff0c;武汉出版社主管&#xff0c;武汉市妇联和武汉出版社联合主办&#xff0c;面向全国发行的人文社科综合期刊。办刊宗旨&#xff1a;宣传普及科学知识及科学方法的研究&#xff1b;倡导新型的人际关系&#xff0c;推介健康的家庭…

OC和Swift的区别,发送消息和执行方法的区别

在 Objective-C 和 Swift 中&#xff0c;方法调用的机制存在显著的区别&#xff0c;具体体现在消息传递和方法调用上。以下是关于这两种机制的详细说明&#xff1a; Objective-C&#xff1a;发送消息 消息传递机制 Objective-C 使用消息传递&#xff08;Message Passing&…

go语言进阶 init() 函数

go 语言包 在一个项目中通常我们需要引入第三方包&#xff0c;我们来看下 当我们导入一个包的时候 发生了什么&#xff1a; 首先我们先详细介绍下两个函数&#xff1a; init(), main() 是 go 语言中的保留函数。我们可以在源码中 定义 init()函数&#xff0c; 此函数会在包导入…

iPhone录音的m4a格式音频文件怎么转成MP3格式?

在日常工作生活中&#xff0c;我们有时会用电脑或手机录音&#xff0c;比如iPhone录音的M4A格式音频&#xff0c;要上传至某些软件或者平台使用&#xff0c;但是有时这些平台或者软件对音频格式有要求&#xff0c;比如有的就只能上传mp3格式的文件。 这个时候我们就需要先将音频…

【Python Cookbook】S01E19 在字符串的开头或者结尾处做文本匹配

目录 问题解决方案讨论 问题 如果我们需要在字符串的开头或者结尾处按照指定的文本模式做检查&#xff0c;例如检查文件的扩展名&#xff0c;URL协议类型等等。 解决方案 检查如扩展名等结尾的文本模式&#xff0c;选择 str.startswith() 方法&#xff0c;检查如URL协议类型…

unity 制作表格 配置

using System.Collections; using System.Collections.Generic; using UnityEngine; [CreateAssetMenu(fileName “exeConfig.asset”, menuName “Config/exeConfig”, order 3)] public class exeConfig : ScriptableObject { public string carName; [Header("表名…

基础IO(上)

前言 文件 内容 属性 所有对文件的操作就是对内容操作和对属性操作。内容是数据&#xff0c;属性也是数据。存储文件&#xff0c;必须既存储内容又存储数据。创建文件默认就是在磁盘中的。我们要访问一个文件的时候&#xff0c;都是要先把这个文件打开的。访问文件的本质就是…

无人机EasyDSS推拉流视频直播技术在农业植保中的精准应用与展望

随着科技的飞速发展&#xff0c;无人机在农业领域的应用越来越广泛&#xff0c;特别是在农业植保方面&#xff0c;无人机以其独特的优势&#xff0c;为农业生产带来了革命性的改变。 无人机在农业植保中的应用主要体现在两个方面&#xff1a;提高工作效率和精准喷洒药物。在以…

每天认识一家仪器仪表厂商 | 横河测试测量官网 - Yokogawa

横河Yokogawa工商信息&#xff1a; 横河测量技术(上海)有限公司于2000年08月09日成立。法定代表人山崎正晴(YAMAZAKI MASAHARU)&#xff0c;公司经营范围包括&#xff1a;从事测量科技、机电科技领域内技术开发、技术转让、技术咨询、技术服务&#xff0c;仪器仪表、通讯设备、…

专业130+总分400+四川大学951信号与系统考研经验川大电子信息与通信工程,真题,大纲,参考书。教材。

今年四川大学951信号与系统专业课130&#xff08;据我所知没有140以上的今年&#xff09;&#xff0c;总分400&#xff0c;顺利上岸川大&#xff0c;回顾一下自己这一年的复习&#xff0c;希望自己的经历可以对大家复习有所借鉴&#xff0c;也是对自己的考研画上句话。专业课&a…

全屋智能的本质是低成本的重构

全屋智能&#xff08;这里指的不是每个电器都可以在APP上控制&#xff0c;而是基于场景化的全屋智能&#xff09;&#xff0c;我第一次去圣都总部听讲的时候是不准备做的&#xff08;我的理解是这玩意儿带来的是至少十万的成本&#xff09;。但随着对于装修各项事物的接触&…

使用from…import语句导入模块

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 在使用import语句导入模块时&#xff0c;每执行一条import语句都会创建一个新的命名空间&#xff08;namespace&#xff09;&#xff0c;并且在该命名…

性格测试.

文章目录 大五人格MBTI九型人格性格测试网站 大五人格 “大五人格"理论&#xff0c;也被称为"五因素模型”&#xff08;Five-Factor Model, FFM&#xff09;或"人格大五结构模型"&#xff0c;是现代心理学中最为广泛接受的人格理论之一。它认为人格特质可…

爬虫案例实战

文章目录 一、窗口切换实战二、京东数据抓取 一、窗口切换实战 案例实战&#xff1a;使用selenium实现打开百度和腾讯两个窗口并切换 知识点&#xff1a;用到selenium中execute_script()执行js代码及switch_to.window()方法 全部代码如下&#xff1a; import time import war…