英文版下载: PHP 5 Power Programming https://www.jb51.net/books/61020.html
PHP取得成功的一个主要原因之一是她拥有大量的可用扩展。web开发者无论有何种需求,这种需求最有可能在PHP发行包里找到。PHP发行包包括支持各种数据库,图形文件格式,压缩,XML技术扩展在内的许多扩展。
扩展API的引入使PHP3取得了巨大的进展,扩展API机制使PHP开发社区很容易的开发出几十种扩展。现在,两个版本过去了,API仍然和PHP3时的非常相似。扩展主要的思想是:尽可能的从扩展编写者那里隐藏PHP的内部机制和脚本引擎本身,仅仅需要开发者熟悉API。
有两个理由需要自己编写PHP扩展。第一个理由是:PHP需要支持一项她还未支持的技术。这通常包括包裹一些现成的C函数库,以便提供PHP接口。例如,如果一个叫FooBase的数据库已推出市场,你需要建立一个PHP扩展帮助你从PHP里调用FooBase的C函数库。这个工作可能仅由一个人完成,然后被整个PHP社区共享(如果你愿意的话)。第二个不是很普遍的理由是:你需要从性能或功能的原因考虑来编写一些商业逻辑。
如果以上的两个理由都和你没什么关系,同时你感觉自己没有冒险精神,那么你可以跳过本章。
本章教你如何编写相对简单的PHP扩展,使用一部分扩展API函数。对于大多数打算开发自定义PHP扩展开发者而言,它含概了足够的资料。学习一门编程课程的最好方法之一就是动手做一些极其简单的例子,这些例子正是本章的线索。一旦你明白了基础的东西,你就可以在互联网上通过阅读文挡、原代码或参加邮件列表新闻组讨论来丰富自己。因此,本章集中在让你如何开始的话题。在UNIX下一个叫ext_skel的脚本被用于建立扩展的骨架,骨架信息从一个描述扩展接口的定义文件中取得。因此你需要利用UNIX来建立一个骨架。Windows开发者可以使用Windows ext_skel_win32.php代替ext_skel。
然而,本章关于用你开发的扩展编译PHP的指导仅涉及UNIX编译系统。本章中所有的对API的解释与UNIX和Windows下开发的扩展都有联系。
当你阅读完这章,你能学会如何
•建立一个简单的商业逻辑扩展。
•建议个C函数库的包裹扩展,尤其是有些标准C文件操作函数比如fopen()
快速开始
本节没有介绍关于脚本引擎基本构造的一些知识,而是直接进入扩展的编码讲解中,因此不要担心你无法立刻获得对扩展整体把握的感觉。假设你正在开发一个网站,需要一个把字符串重复n次的函数。下面是用PHP写的例子:
复制代码 代码如下:
function self_concat($string, $n){
$result = "";
for($i = 0; $i < $n; $i++){
$result .= $string;
}
return $result;
}
self_concat("One", 3) returns "OneOneOne".
self_concat("One", 1) returns "One".
假设由于一些奇怪的原因,你需要时常调用这个函数,而且还要传给函数很长的字符串和大值n。这意味着在脚本里有相当巨大的字符串连接量和内存重新分配过程,以至显著地降低脚本执行速度。如果有一个函数能够更快地分配大量且足够的内存来存放结果字符串,然后把$string重复n次,就不需要在每次循环迭代中分配内存。
为扩展建立函数的第一步是写一个函数定义文件,该函数定义文件定义了扩展对外提供的函数原形。该例中,定义函数只有一行函数原形self_concat() :
复制代码 代码如下:
string self_concat(string str, int n)
函数定义文件的一般格式是一个函数一行。你可以定义可选参数和使用大量的PHP类型,包括: bool, float, int, array等。
保存为myfunctions.def文件至PHP原代码目录树下。
该是通过扩展骨架(skeleton)构造器运行函数定义文件的时机了。该构造器脚本叫ext_skel,放在PHP原代码目录树的ext/目录下(PHP原码主目录下的README.EXT_SKEL提供了更多的信息)。假设你把函数定义保存在一个叫做myfunctions.def的文件里,而且你希望把扩展取名为myfunctions,运行下面的命令来建立扩展骨架
复制代码 代码如下:
./ext_skel --extname=myfunctions --proto=myfunctions.de
这个命令在ext/目录下建立了一个myfunctions/目录。你要做的第一件事情也许就是编译该骨架,以便编写和测试实际的C代码。编译扩展有两种方法:
•作为一个可装载模块或者DSO(动态共享对象)
•静态编译到PHP
PHP扩展开发导图
因为第二种方法比较容易上手,所以本章采用静态编译。如果你对编译可装载扩展模块感兴趣,可以阅读PHP原代码根目录下的README.SELF-CONTAINED_EXTENSIONS文件。为了使扩展能够被编译,需要修改扩展目录ext/myfunctions/下的config.m4文件。扩展没有包裹任何外部的C库,你需要添加支持–enable-myfunctions配置开关到PHP编译系统里(–with-extension 开关用于那些需要用户指定相关C库路径的扩展)。可以去掉自动生成的下面两行的注释来开启这个配置。
复制代码 代码如下: