这篇文章将会系统的介绍如何开发自己的PHP扩展, 也许你会说,网上这样的文章已经很多了,为什么还要写? 呵呵,我当然不会只是简单的重复。 这篇文章将会涉及到很多的高级技术,比如在自己的扩展中使用资源,开发一个类给脚本使用,在PHP中使用C++的对象等等,另外这篇文章还会穿插很多Zend引擎和PHP内核的知识,比如变量的实现,资源的实现,PHP4和PHP5对类的不同实现等等
首先,我们要有个认识,那就是在php中的类和函数,以至于变量,在本质上都是C实现的。 你所编写的脚本,最终都会被转换成C代码来执行。 这个和我在以前文章中(深入理解PHP原理之Opcodes)介绍的opcode并不冲突, 因为Zend虚拟机的指令最终还是要翻译成C代码来执行。
开发者也就可以使用C/C++来写一些PHP的函数,类。从而扩展PHP, 那么,为什么要扩展PHP呢? 很多同学只是盲目的去扩展,认为扩展PHP是一个很有“意义”的事(许三多语气),而我认为,扩展PHP只是在特定的情况才有必要,最主要的俩个原因是:
其实第二个理由,已经是很充足了,但是用扩展来实现你的逻辑,并不是那么简单的事情:
首先如果你是使用PHP来实现你的逻辑,那么你不需要考虑资源管理,Zend会替你完成。其次你也不需要担心, 代码的一个简单的错误,就会导致PHP core dump。
而如果你用C来编写PHP的扩展,那么你就要自己考虑这些事情,自己管理资源的分配,使用,释放。 你也要学会适应segmentation fault :)。 我要提醒你的是, 因为PHP是一个长时间运行的模块(因为Apache是一个长时间运行的Web服务器), 所以,你千万要防止资源泄露, 我就遇到过一个简单的字符串泄露, 在一段时间以后,Apache占用的内存超过了1个G。
接下来,总结一下用C/C++扩展PHP的优缺点:
优点:
而缺点也是显而易见的:
恩,现在你看到了, 用C/C++实现PHP扩展的优点和缺点了,那么你就可以自己权衡你的逻辑,是要用那种方式实现了。呵呵
如果你熟悉C,那么编写一个PHP扩展,并不是什么非常难的事情。 PHP本身就提供了一个框架,来简化你的开发。
最简单的方式来开始一个PHP扩展的开发,是使用PHP提供的扩展框架wizard ext_skel, 它会生成一个PHP扩展所必须的最基本的代码, 要使用它,首先你要下载PHP的源码,或者开发包, 进入PHP源码的ext目录, 就会发现这个工具。比如我下载了PHP源码php5.2-SRC到/home/xinchen/,那么这个工具的路径就在: /home/xinchen/php5.2-SRC/ext下。
这个工具的使用方式也很简单, 比如我们要创建一个名叫example的扩展,那么:
这样,就在ext目录下生成了一个名为example的目录,并在这个目录下生成了所有的要完成一个PHP扩展所必须的文件和代码(事实上,这个目录下的文件,已经可以生成一个PHP的标准扩展了,只不过这个扩展不完成任何功能,就好像我们使用Visual Studio的Wizard生成的一个空的MFC框架一样)。接下来,我们要做的就是不停的重复最后俩个步骤,从而实现我们的功能。
在这个目录下,我们要尤其关注的是example.c这个文件,这个文件是我们扩展的主要文件,也就是说,如果我们要充实我们的扩展,那么就需要在这个文件中进行工作。 在后面的内容中,我会消息介绍这个文件中包含的各个字段,结构的含义,现在我们就只是简单的掠过他。
第二个要特别注意的文件就是config.m4,如果读者你有过在Unix/Linux下的编程经历,那么你或许听过autoconf和m4, m4是一个宏解释工具,它会把输入文件中的宏展开到输出文件。所以这个config.m4是PHP扩展框架所必须的,也是关键的一个文件,用来生成我们扩展的makefile。
在config.m4中,有一行:
在m4中,dnl表示注释, 这段指令创建了一个configure时的参数“enable-example”, 第二个参数会显示在当configure处理到这个模块的configure文件的时候。第三个参数,会在用户输入./configurehelp的时候,作为一个可选的选项被显示。
另外还有一段:
严格来说,上面的俩段没有太大的区别,只不过with是说明了,要启用这个模块,必须要的先决条件,也就是说这个模块依赖于某些其他模块。
就好像:
PHP的扩展框架构建系统,支持全套的.m4语法,当然还支持用户自定义的宏, 下面我介绍一些常见的,由PHP扩展框架构建系统定义的宏:
更多的由PHP扩展框架构建系统提供的宏,你可以到acinclude.m4中查看。
还有一些其他的有ext_skel创建的文件:
CREDITES 这个文件没什么太大的作用,只是用来在发布你的扩展的时候附加一些其他信息 ,比如作者啊,等等。
EXPERIMENTAL 这个文件只是标志说,这个扩展是实验性的,所以你可以不用管它
example.php 这个文件是用来简单测试你的扩展的
php_example.h 这个是我们扩展的头文件
tests/001.phpt 这个也是个测试文件, 不过使用的是单元测试, 阶段测试, 具体内容,你打开一看便知 ;)
下一次我讲介绍一些要开发扩展,最好要先了解的知识,比如变量的内部表示,copy-on-write , change-on-write机制, 函数的内部表示==。 当然,这其中有些知识是我以前的文章已经涉及过的:
PHP的函数(Introspecting PHP Function)
恩,这个文章要持续开发。
[回复]
顶,学习了
[回复]
很难啃,舔一舔也好
[回复]
部分内容似乎在哪见过,不过写的不错,支持博主。
[回复]
恩,网上有不少介绍扩展PHP的文章,;) “也许你会说,网上这样的文章已经很多了,为什么还要写?”
[回复]
网上有很多类似文章,但介绍的要么过于简单,要么过于艰深,希望博主再接在励。
[回复]
恩,有些内容我不会完全归类到这个系列下面,但是确实和这个系列相关的。最后我会把相关的东西整理起来,所以你可以看看我其他的文章,不一定等我归类到这个系列后再看,;)
[回复]
强烈支持楼主,非常好的文章!
[回复]
希望楼主继续写关于扩展方面的文章.加油!
[回复]