【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;
}
相关文章:
【PECL】在扩展中实现 autoload
【PECL】在扩展中实现 autoload 摘要PHP代码想这么写C 代码这么实现 摘要 php-8.3.x 用扩展写个框架。想实现类管理器,自动加载,上代码: PHP代码想这么写 $ws new \Ziima\Applet(); $ws->import(Ziima, ../base/core); $ws->runAu…...
企业微信H5授权登录
在企业中如果需要在打开的网页里面携带用户的身份信息,第一步需要获取code参数 如何实现企业微信H5获取当前用户信息即accessToken? 1.在应用管理--》创建应用 2.创建好应用,点击应用主页-》设置-》网页-》将授权链接填上去 官方文档可以看…...
玩机进阶教程------修改gpt.bin分区表地址段 完全屏蔽系统更新 fast刷写分区表 操作步骤解析【二】
上期博文简单说明了分区表的基本常识。我们在有些环境中需要屏蔽手机的系统更新选项。除了以前博文中说明的修改系统更新下载文件夹的方法。还可以通过修改分区表类达到目的。在一些辅助维修工具上面带修改分区表功能。修改后效果为屏蔽系统更新和可以恢复出厂。原则上不深刷都…...
Java实现数据结构---数组
文章目录 概念存储原理数组的操作完整代码 概念 数组是(Array)是有限个相同类型的变量所组成的有序集合,数组中的每一个变量为称为元素。数组是最简单、最常用的数据结构。 数组下标从零开始。 存储原理 数组用一组连续的内存空间来存储一…...
java解析excel文件,返回json
我这里用的是springboot项目,配合Maven使用的。首先需要引入依赖: <dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>4.1.2</version></dependency><dependency…...
uniapp 添加字体ttf
效果图如下 一、逻辑概述 在uniapp中使用字体,一共分成两种情况,一种是普通vue页面,一种是nvue页面引入字体。。 1.vue页面引入字体需要如下步骤 1. 先选择下载一种字体:字体格式一般为 ttf后缀名 黄凯桦律师手写体免费下载和在线…...
Linux入门攻坚——24、BIND编译安装、Telnet和OpenSSH
BIND编译安装 对于没有rpm包,需要源代码编译安装。 1、下载源代码:bind-9.12.2-P1.tar.gz,解压:tar -xf bind-9.12.2-P1.tar.gz 2、完善环境: 1)增加用户组named:groupadd -g 53 named 2&…...
1.5.3 基于Java配置方式使用Spring MVC
本实战教程主要介绍了如何使用Java配置方式来使用Spring MVC框架。相较于XML配置方式,Java配置方式提供了一种更为简洁和灵活的配置方法。 项目创建与配置 创建一个Jakarta EE项目,并设置项目名称和位置。选择Jakarta EE 10版本,不添加依赖&a…...
Artifactory清理二进制文件丢失的制品
一、摘要 当制品上传到 Artifactory 时,Artifactory 会在数据库中记录制品的相关元数据信息,包括文件路径、大小、校验和(如 MD5、SHA1)、上传时间、索引、依赖等。实际的制品二进制文件会存储在指定的存储后端,具体的…...
C#中的数组探索
在C#编程语言中,数组是一种基本的数据结构,用于存储固定大小的同类型元素序列。本文将深入探讨C#数组的各个方面,包括定义、赋值、范围操作、切片、多维数组(矩形与锯齿形)、简化初始化表达式以及边界检查。 数组定义…...
身份认证与口令攻击
身份认证与口令攻击 身份认证身份认证的五种方式口令认证静态口令动态口令(一次性口令)动态口令分类 密码学认证一次性口令认证S/KEY协议改进的S/KEY协议 其于共享密钥的认证 口令行为规律和口令猜测口令规律口令猜测 口令破解操作系统口令破解Windows密码存储机制Windows密码破…...
卷积网络迁移学习:实现思想与TensorFlow实践
摘要:迁移学习是一种利用已有知识来改善新任务学习性能的方法。 在深度学习中,迁移学习通过迁移卷积网络(CNN)的预训练权重,实现了在新领域或任务上的高效学习。 下面我将详细介绍迁移学习的概念、实现思想,…...
Ansible04-Ansible Vars变量详解
目录 写在前面6 Ansible Vars 变量6.1 playbook中的变量6.1.1 playbook中定义变量的格式6.1.2 举例6.1.3 小tip 6.2 共有变量6.2.1 变量文件6.2.1.1 变量文件编写6.2.1.2 playbook编写6.2.1.3 运行测试 6.2.2 根据主机组使用变量6.2.2.1 groups_vars编写6.2.2.2 playbook编写6.…...
Flutter 中的 SliverCrossAxisGroup 小部件:全面指南
Flutter 中的 SliverCrossAxisGroup 小部件:全面指南 Flutter 是一个功能丰富的 UI 开发框架,它允许开发者使用 Dart 语言来构建高性能、美观的移动、Web 和桌面应用。在 Flutter 的丰富组件库中,SliverCrossAxisGroup 是一个较少被使用的组…...
开源还是闭源这是一个问题
天行健,君子以自强不息;地势坤,君子以厚德载物。 每个人都有惰性,但不断学习是好好生活的根本,共勉! 文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。…...
数据结构与算法笔记:基础篇 - 栈:如何实现浏览器的前进和后退功能?
概述 浏览器的前进、后退功能,你肯定很熟悉吧? 当依次访问完一串页面 a-b-c 之后,点击浏览器的后退按钮,就可以查看之前浏览过的页面 b 和 a。当后退到页面 a,点击前进按钮,就可以重新查看页面 b 和 c。但…...
【AIGC】大型语言模型在人工智能规划领域模型生成中的探索
大型语言模型在人工智能规划领域模型生成中的新应用 一、引言二、LLM在规划领域模型生成中的潜力三、实证分析:LLM在规划领域模型生成中的表现四、代码实例:LLM在规划领域模型生成中的应用五、结论与展望 一、引言 随着人工智能技术的迅猛发展࿰…...
从零开始学习Slam-旋转矩阵旋转向量四元组(二)
本文参考:计算机视觉life 仅作笔记用 书接上回,上回不清不楚的介绍了旋转矩阵&旋转向量和四元组 现在回顾一下重点: 本着绕谁谁不变的变则 假设绕z轴旋转θ,旋转矩阵为: 再回顾一下旋转向量的表示以及这个基本记不…...
基于Spring Security添加流控
基于Spring Security添加流控的过程: 步骤1: 添加依赖 确保项目中包含了Spring Security和Sentinel-Core的相关依赖。在Maven项目中,可以在pom.xml中添加如下依赖: <!-- Spring Security --> <dependency><groupId>org.…...
Python | Leetcode Python题解之第119题杨辉三角II
题目: 题解: class Solution:def getRow(self, rowIndex: int) -> List[int]:row [1, 1]if rowIndex < 1:return row[:rowIndex 1]elif rowIndex > 2:for i in range(rowIndex - 1):row [row[j] row[j 1] for j in range(i 1)]row.inser…...
在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能
下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能,包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...
智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制
在数字化浪潮席卷全球的今天,数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具,在大规模数据获取中发挥着关键作用。然而,传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时,常出现数据质…...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...
sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!
简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求,并检查收到的响应。它以以下模式之一…...
使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...
音视频——I2S 协议详解
I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议,专门用于在数字音频设备之间传输数字音频数据。它由飞利浦(Philips)公司开发,以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...
如何在Windows本机安装Python并确保与Python.NET兼容
✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…...
