没有合适的资源?快使用搜索试试~ 我知道了~
首页Zend API:深入 PHP 内核
Zend API:深入 PHP 内核
5星 · 超过95%的资源 需积分: 9 11 下载量 133 浏览量
更新于2023-03-03
评论
收藏 916KB PDF 举报
“扩展 PHP”说起来容易做起来难。PHP 现在已经发展成了一个具有数兆字节源代码的非常成熟的系统。要想深入这样的一个系统,有很多东西需要学习和考虑。在写这一章节的时候,我们最终决定采用“边学边做”的方式。这也许并不是最科学和专业的方式,但却应该是最有趣和最有效的一种方式。在下面的小节里,你首先会非常快速的学习到如何写一个虽然很基础但却能立即运行的扩展,然后将会学习到有关 Zend API 的高级功能。另外一个选择就是将其作为一个整体,一次性的讲述所有的这些操作、设计、技巧和诀窍等,并且可以让我们在实际动手前就可以得到一副完整的愿景。这看起来似乎是一个更好的方法,也没有死角,但它却枯燥无味、费时费力,很容易让人感到气馁。这就是我们为什么要采用非常直接的讲法的原因。
资源详情
资源评论
资源推荐
Zend API:深入 PHP 内核
by yAnbiN ben.yan@msn.com
( 二 ) 摘 要
摘要
知者不言,言者不知。
――老子《道德经》五十六章
有时候,单纯依靠 PHP“本身”是不行的。尽管普通用户很少遇到这种情况,但一些专业性的应用则经常需
要将 PHP 的性能发挥到极致(这里的性能是指速度或功能)。由于受到 PHP 语言本身的限制,同时还可
能不得不把庞大的库文件包含到每个脚本当中,因此,某些新功能并不是总能被顺利实现,所以我们必须
另外寻找一些方法来克服 PHP 的这些缺点。
了解到了这一点,我们就应该接触一下 PHP 的心脏并探究一下它的内核--可以编译成 PHP 并让之工
作的 C 代码--的时候了。
( 三 ) 概 述
概述
“扩展 PHP”说起来容易做起来难。PHP 现在已经发展成了一个具有数兆字节源代码的非常成熟的系统。
要想深入这样的一个系统,有很多东西需要学习和考虑。在写这一章节的时候,我们最终决定采用“边学边
做”的方式。这也许并不是最科学和专业的方式,但却应该是最有趣和最有效的一种方式。在下面的小节里,
你首先会非常快速的学习到如何写一个虽然很基础但却能立即运行的扩展,然后将会学习到有关 Zend
API 的高级功能。另外一个选择就是将其作为一个整体,一次性的讲述所有的这些操作、设计、技巧和诀
窍等,并且可以让我们在实际动手前就可以得到一副完整的愿景。这看起来似乎是一个更好的方法,也没
有死角,但它却枯燥无味、费时费力,很容易让人感到气馁。这就是我们为什么要采用非常直接的讲法的
原因。
注意,尽管这一章会尽可能多讲述一些关于 PHP 内部工作机制的知识,但要想真的给出一份在任何时间
任何情况下的 PHP 扩展指南,那简直是不可能的。PHP 是如此庞大和复杂,以致于只有你亲自动手实践
一下才有可能真正理解它的内部工作机制,因此我们强烈推荐你随时参考它的源代码来进行工作。
Zend 是什么? PHP 又是什么?
Zend 指的是语言引擎,PHP 指的是我们从外面看到的一套完整的系统。这听起来有点糊涂,但其实并不
复杂(见图 3-1 PHP 内部结构图)。为了实现一个 WEB 脚本的解释器,你需要完成以下三个部分的工
作:
1、 解释器部分,负责对输入代码的分析、翻译和执行;
2、 功能性部分,负责具体实现语言的各种功能(比如它的函数等等);
3、 接口部分,负责同 WEB 服务器的会话等功能。
Zend 包括了第一部分的全部和第二部分的局部,PHP 包括了第二部分的局部和第三部分的全部。他们合
起来称之为 PHP 包。Zend 构成了语言的核心,同时也包含了一些最基本的 PHP 预定义函数的实现。
PHP 则包含了所有创造出语言本身各种显著特性的模块。
图 3-1 PHP 内部结构图
下面将要讨论 PHP 允许在哪里扩展以及如何扩展。
( 四 ) 可 扩展性
正如上图(图 3-1 PHP 内部结构图)所示,PHP 主要以三种方式来进行扩展:外部模块,内建模块各 Zend
引擎。下面我们将分别讨论这些方式:
外部模块
外部模块可以在脚本运行时使用 dl() 函数载入。这个函数从磁盘载入一个共享对象并将它的功能与调用该
函数的脚本进行绑定并使之生效。脚本终止后,这个外部模块将在内存中被丢弃。这种方式有利有弊,如
下表所示:
优点
缺点
外部模块不需要重新
对 PHP 进行编译。
共享对象在每次脚本调用时都需要对其进行加载,速度较慢。
PHP 通过“外包”方式
来让自身的体积保持
很小。
附加的外部模块文件会让磁盘变得比较散乱。
每个想使用该模块功能的脚本都必须使用 dl() 函数手动加载,
或者在 php.ini 文件当中添加一些扩展标签(这并不总是一个恰
当的解决方案)。
综上所述,外部模块非常适合开发第三方产品,较少使用的附加的小功能或者仅仅是调试等这些用途。为
了迅速开发一些附加功能,外部模块是最佳方式。但对于一些经常使用的、实现较大的,代码较为复杂的
应用,那就有些得不偿失了。
第三方可能会考虑在 php.ini 文件中使用扩展标签来创建一个新的外部模块。这些外部模块完全同主 PHP
包分离,这一点非常适合应用于一些商业环境。商业性的发行商可以仅发送这些外部模块而不必再额外创
建那些并不允许绑定这些商业模块的 PHP 二进制代码。
内建模块
内建模块被直接编译进 PHP 并存在于每一个 PHP 处理请求当中。它们的功能在脚本开始运行时立即生
效。和外部模块一样,内建模块也有各有利弊,列表如下:
优点
缺点
无需专门手动载入,功能即时生效。
修改内建模块时需要重新编译 PHP。
无需额外的磁盘文件,所有功能均内置在 PHP 二
进制代码当中。
PHP 二进制文件会变大并且会消耗
更多的内存。
Zend 引擎
当然,你也能直接在 Zend 引擎里面进行扩展。如果你需要在语言特性方面做些改动或者是需要在语言核
心内置一些特别的功能,那么这就是一种很好的方式。但一般情况下应该尽力避免对 Zend 引擎的修改。
这里面的改动会导致和其他代码的不兼容,而且几乎没有人会适应打过特殊补丁的 Zend 引擎。况且这些
改动与主 PHP 源代码是不可分割的,因此就有可能在下一次的官方的源代码更新中被覆盖掉。因此,这
种方式通常被认为是“不良的习惯”。由于使用极其稀少,本章将不再对此进行赘述。
( 五 ) 源 码 布 局
在我们开始讨论具体编码这个话题前,你应该让自己熟悉一下 PHP 的源码树以便可以迅速地对各个源文
件进行定位。这也是编写和调试 PHP 扩展所必须具备的一种能力。
下表列出了一些主要目录的内容:
目录
内容
php-src
包含了 PHP 主源文件和主头文件;在这里你可以找到所有的 PHP API 定
义、宏等内容。(重要). 其他的一些东西你也可以在这里找到。
php-src/ext
这里是存放动态和内建模块的仓库;默认情况下,这些就是被集成于主
源码树中的“官方” PHP 模块。自 PHP 4.0 开始,这些 PHP 标准扩展都
可以编译为动态可载入的模块。(至少这些是可以的)。
php-src/main
这个目录包含主要的 PHP 宏和定义。 (重要)
php-src/pear
这个目录就是“PHP 扩展与应用仓库”的目录。包含了 PEAR 的核心文件。
php-src/sapi
包含了不同服务器抽象层的代码。
TSRM
Zend 和 PHP 的 “线程安全资源管理器” (TSRM) 目录。
ZendEngine2
包含了 Zend 引擎文件;在这里你可以找到所有的 Zend API 定义与宏
等。(重要)
当然,讨论 PHP 包里面全部每一个文件无疑是超出了本章的范围,但你还是应该仔细看一下下面的几个
文件:
php-src/main/php.h, 位于 PHP 主目录。这个文件包含了绝大部分 PHP 宏及 API 定义。
php-src/Zend/zend.h, 位于 Zend 主目录。这个文件包含了绝大部分 Zend 宏及 API 定义。
php-src/Zend/zend_API.h, 也位于 Zend 主目录,包含了 Zend API 的定义。
除此之外,你也应该注意一下这些文件所包含的一些文件。举例来说,哪些文件与 Zend 执行器有关,哪
些文件又为 PHP 初始化工作提供了支持等等。在阅读完这些文件之后,你还可以花点时间再围绕 PHP 包
来看一些文件,了解一下这些文件和模块之间的依赖性――它们之间是如何依赖于别的文件又是如何为其
他文件提供支持的。同时这也可以帮助你适应一下 PHP 创作者们代码的风格。要想扩展 PHP,你应该尽
快适应这种风格。
扩展规范
Zend 是用一些特定的规范构建的。为了避免破坏这些规范,你应该遵循以下的几个规则:
宏
几乎对于每一项重要的任务,Zend 都预先提供了极为方便的宏。在下面章节的图表里将会描述到大部分
基本函数、结构和宏。这些宏定义大多可以在 Zend.h 和 Zend_API.h 中找到。我们建议您在学习完本节
之后仔细看一下这些文件。(当然你也可以现在就阅读这些文件,但你可能不会留下太多的印象。)
内存管理
资源管理仍然是一个极为关键的问题,尤其是对服务器软件而言。资源里最具宝贵的则非内存莫属了,内
存管理也必须极端小心。内存管理在 Zend 中已经被部分抽象,而且你也应该坚持使用这些抽象,原因显
而易见:由于得以抽象,Zend 就可以完全控制内存的分配。Zend 可以确定一块内存是否在使用,也可以
自动释放未使用和失去引用的内存块,因此就可以避免内存泄漏。下表列出了一些常用函数:
函数
描述
emalloc()
用于替代 malloc()。
efree()
用于替代 free()。
estrdup()
用于替代 strdup()。
estrndup()
用于替代 strndup()。速度要快于 estrdup() 而且是二进制安全的。如果你
在复制之前预先知道这个字符串的长度那就推荐你使用这个函数。
ecalloc()
用于替代 calloc()。
erealloc()
用于替代 realloc()。
emalloc(), estrdup(), estrndup(), ecalloc(), 和 erealloc() 用于申请内部的内存,efree() 则用来释放这些
前面这些函数申请的内存。e*() 函数所用到的内存仅对当前本地的处理请求有效,并且会在脚本执行完毕,
处理请求终止时被释放。
Zend 还有一个线程安全资源管理器,这可以为多线程 WEB 服务器提供更好的本地支持。不过这需要你
为所有的全局变量申请一个局部结构来支持并发线程。但是因为在写本章内容时 Zend 的线程安全模式仍
未完成,因此我们无法过多地涉及这个话题。
目录与文件函数
下列目录与文件函数应该在 Zend 模块内使用。它们的表现和对应的 C 语言版本完全一致,只是在线程
级提供了虚拟目录的支持。
Zend 函数
对应的 C 函数
V_GETCWD()
getcwd()
V_FOPEN()
fopen()
V_OPEN()
open()
V_CHDIR()
chdir()
V_GETWD()
getwd()
V_CHDIR_FILE()
将当前的工作目录切换到一个以文件名为参数的该文件所在的目录。
V_STAT()
stat()
V_LSTAT()
lstat()
字符串处理
在 Zend 引擎中,与处理诸如整数、布尔值等这些无需为其保存的值而额外申请
内存的简单类型不同,如果你想从一个函数返回一个字符串,或往符号表新建一
个字符串变量,或做其他类似的事情,那你就必须确认是否已经使用上面的 e*()
等函数为这些字符串申请内存。(你可能对此没有多大的感觉。无所谓,现在你
只需在脑子里有点印象即可,我们稍后就会再次回到这个话题)
复杂类型
剩余61页未读,继续阅读
tfxg
- 粉丝: 48
- 资源: 4
上传资源 快速赚钱
- 我的内容管理 收起
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
会员权益专享
最新资源
- 2022年中国足球球迷营销价值报告.pdf
- 房地产培训 -营销总每天在干嘛.pptx
- 黄色简约实用介绍_汇报PPT模板.pptx
- 嵌入式系统原理及应用:第三章 ARM编程简介_3.pdf
- 多媒体应用系统.pptx
- 黄灰配色简约设计精美大气商务汇报PPT模板.pptx
- 用matlab绘制差分方程Z变换-反变换-zplane-residuez-tf2zp-zp2tf-tf2sos-sos2tf-幅相频谱等等.docx
- 网络营销策略-网络营销团队的建立.docx
- 电子商务示范企业申请报告.doc
- 淡雅灰低面风背景完整框架创业商业计划书PPT模板.pptx
- 计算模型与算法技术:10-Iterative Improvement.ppt
- 计算模型与算法技术:9-Greedy Technique.ppt
- 计算模型与算法技术:6-Transform-and-Conquer.ppt
- 云服务安全风险分析研究.pdf
- 软件工程笔记(完整版).doc
- 电子商务网项目实例规划书.doc
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论2