手机版

谈PHP扩展——基础1/2页的开发

时间:2021-10-21 来源:互联网 编辑:宝哥软件园 浏览:

引言PHP是目前使用非常广泛的一种语言,从国外的脸书和Twitter,国内的淘宝、腾讯、百度以及互联网上的各种大、中、小网站都可以看到。PHP的成功很大程度上取决于其开放的扩展API机制和丰富的扩展组件(PHP Extension),这使得PHP从各种数据库操作到XML、JSON、加密、文件处理、图形处理、Socket等领域无所不能。有时候,开发人员可能需要开发自己的PHP扩展。目前PHP5的扩展机制基于Zend API,提供了丰富的接口和宏定义,加上一些实用的工具,开发PHP扩展并不是特别困难。本文将介绍开发PHP扩展组件的基本知识,并通过一个实例展示开发PHP扩展的基本过程。在Unix和Windows环境下,PHP扩展组件的开发过程是不同的,但它们基本上是可互操作的。本文将基于Unix环境(特别是使用Linux)。阅读本文需要简单了解Unix环境、PHP和C语言的一些基本知识。只要简单,我就尽量不涉及太具体的操作系统和语言特性,必要的地方给读者讲解一下。本文的具体开发环境是Ubuntu 10.04 PHP 5.3.3。要下载PHP源代码开发PHP扩展,第一步是下载PHP源代码,因为开发扩展需要工具。我下载了tar.bz2压缩包中最新版本的PHP 5 . 3 . 3。下载地址:http://cn.php.net/get/php-5.3.3.tar.bz2/from/a/mirror.下载后,将源代码移动到适当的目录并解压缩。解压命令为:复制代码如下:tar -jxvf源代码包名。如果下载了tar.gz压缩包,解压缩命令是复制如下代码:tar -zxvf源代码包名。解压后,源代码目录中有一个ext目录,是与PHP扩展相关的目录。进入目录后,用ls检查,可以看到很多已有的扩展名。下图是在我的环境下查看的结果:image

其中蓝色的都是扩展包目录,在里面可以看到熟悉的mysql、iconv、gd等。而ext_skel是一个在Unix环境下自动生成PHP扩展框架的脚本工具,我们马上就会用到。ext_skel_win32.php是windows下对应的脚本。开发自己的PHP扩展——say_hello。接下来,我们将开发一个PHP扩展:say_hello。这个扩展非常简单,只需要接受一个字符串参数,然后输出“你好xxx!”。这个例子只是为了介绍PHP扩展组件的开发过程,并不承担实际的功能。生成扩展组件框架的PHP的扩展组件开发目录和文件有固定的组织结构。您可以输入现有的扩展组件目录,并随意查看其所有文件。我想你一定眼花了。当然,你可以选择手工完成框架,但我相信你宁愿有东西来帮助你完成它。上面提到的ext_skel脚本是一个自动构建扩展包框架的工具。ext_skel的完整命令是:ext _ skel-ext name=module[-proto=file][-stubs=file][-XML[=file]][-skel=dir][-full-XML][-no-help]作为初学者。因此,我们在ext目录中键入以下命令:/ext_skel-extname=say_hello(如果想了解ext_skel的更多命令参数,请参考此处)。当您用ls查看它时,您会发现有一个额外的“say_hello”目录。当你进入这个目录,你会发现ext _ skel已经为我们建立了say _ hello的基本框架。

如果你懒得弄清楚服务器端编程语言(专业超文本预处理器的缩写)扩展包目录结构的全部内容,那么里面有三个文件你必须注意:config.m4:这是Unix操作系统操作系统环境下的构建系统配置文件,后面将会通过它生成配置和安装php_say_hello.h:这个文件是扩展模块的头文件。遵循C语言一贯的作风,这个里面可以放置一些自定义的结构体、全局变量等等问好c:这个就是扩展模块的主程序文件了,最终的扩展模块各个函数入口都在这里。当然,你可以将所有程序代码都塞到这里面,也可以遵循模块化思想,将各个功能模块放到不同文件中。下面的内容主要围绕这三个文件展开。

Unix Build System配置

开发服务器端编程语言(专业超文本预处理器的缩写)扩展组件的第一步不是写实现代码,而是要先配置好构建系统选项。由于我们是在Linux操作系统操作系统下开发,所以这里的配置主要与config.m4有关。关于构建系统配置这一块,要是写起来能写一大堆,而且与Unix操作系统操作系统系统很多东西相关,就算我有兴趣写估计大家也没兴趣看,所以这里我们从略,只拣关键地方说一下,关于config.m4更多细节可以参考这里。打开生成的config.m4文件,内容大致如下:复制代码代码如下: dnl $Id$ dnl config.m4扩展名为说你好此文件中的注释以字符串“dnl”开头。必要时移除dnl .如果不进行编辑,该文件将无法正常工作dnl .如果您的扩展引用了外部的东西,请使用用: dnl PHP _ ARG _ WITH(打个招呼,用于说你好支持dnl确保注释对齐: dnl[-wit-say _ hello包括说你好支持]) dnl否则使用启用: dnl PHP _ ARG _ ENABLE(SAY _ HELLO,是否启用说你好支持dnl确保注释对齐: dnl[-ENABLE-SAY _ HELLO ENABLE _ SAY _ ENABLE=]否;然后在这里写更多的测试例子.# dnl-with-SAY _ HELLO-check with-PATH dnl SEarch _ PATH='/usr/local/usr ' #您可能希望更改此dnl SEarch _ FOR='/include/SAY _ HELLO。h ' #如果测试-r $PHP_SAY_HELLO/$SEARCH_FOR,您很可能希望更改此dnl然后#路径作为参数给定dnl SAY _ HELLO _ DIR=$ PHP _ SAY _ HELLO dnl else #搜索默认路径列表dnl AC _ MSG _ CHECKING([对于默认路径中的说你好文件]) dnl为我在$ SEARCH _ PATH做dnl if测试-r $ I/$ SEarch _ FOR;然后dnl SAY _ HELLO _ DIR=$ I dnl AC _ MSG _ RESULT(在一美元中找到)dnl fi dnl完成dnl fi dnl如果测试-z ' $ SAY _ HELLO _ DIR ';然后dnl交流_味精_结果([未找到])dnl AC _ MSG _ ERROR([请重新安装说你好分发版])dnlfi dnl #-WITH-SAY _ HELLO-ADD INCLUDE路径dnl PHP _ ADD _ INCLUDE($ SAY _ HELLO _ DIR/INCLUDE)dnl #-WITH-SAY _ HELLO-检查解放运动和符号是否存在dnl LIBNAME=say_hello #您可能希望更改此dnl LIBSYMBOL=说_hello #您最有可能希望更改此dnl PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL这个结构体可能看起来会让人有点头疼,不过我还是要解释一下里面的内容。因为这就是服务器端编程语言(Professional Hypertext Preprocessor的缩写)扩展的原型,如果不搞清楚,就没法开发服务器端编程语言(Professional Hypertext Preprocessor的缩写)扩展了。当然,我就不一一对每个字段进行解释了,只拣关键的、这篇文章会用到的字段说,因为许多字段并不需要我们手工填写,而是可以使用某些预定义的宏填充。第七个字段"名字",这个字段是此服务器端编程语言(Professional Hypertext Preprocessor的缩写)扩展的名字,在本例中就是说你好。第8个字段"功能",这个将存放我们在此扩展中定义的函数的引用,具体结构不再分析,有兴趣的朋友可以阅读_zend_function_entry的源代码。具体编写代码时这里会有相应的宏。

第9-12个字段是4个函数指针,这4个函数会在对应的时间被调用,分别是“加载扩展模块的时候”、“卸载扩展模块的时候”、“每个请求开始的时候”和“每个请求结束的时候”。这四个功能可以看作是一种拦截机制,主要用于相应时间的资源分配、释放等相关操作。第13个字段“info_func”也是一个函数指针,执行phpinfo()时会调用这个指针指向的函数,用来显示自定义模块信息。第14个字段“版本”是模块的版本。(关于zend_module_entry的更详细介绍,请参考这里。)介绍完以上字段,我们可以看看“say_hello.c”中自动生成的“say_hello_module_entry”框架代码。复制的代码如下:/* { { say _ hello _ MODULE _ entry */Zend _ MODULE _ entry say _ hello _ MODULE _ entry={ # ifzend _ MODULE _ API _ NO=20010901 STANDARD _ MODULE _ header,#endif 'say_hello ',say_hello_functions,PHP_MINIT(say_hello),PHP_MSHUTDOWN(say_hello),PHP_RINIT(say_hello),/*如果在请求启动时没有事情可做,则替换为NULL/* } } } */首先宏“STANDARD_MODULE_HEADER”会生成前六个字段,“STANDARD_MODULE_PROPERTIES”会生成“version”之后的字段,所以我们现在不用担心。而且我们关心的几个字段都是宏填充或者生成的,在“say_hello.c”对应的位置也生成了几个函数框架。这里需要注意的是,几个宏的参数都是“say_hello”,但这并不意味着几个函数的名字都是“say_hello”,C语言中也没有函数名重载机制。实际上,在开发PHP Extension的过程中,Zend中预定义的各种宏几乎无处不在。从全局变量到函数甚至返回值的定义,C语言都不能用“赤裸裸”的方式来写。这是因为PHP的运行机制可能会导致命名冲突等问题,这些宏会将函数等元素转换成内部名称,但这些对程序员来说是透明的(除非你阅读了那些宏的代码)。在这一点上,我们的任务是明确的:第一,如果我们需要在相应的时间处理一些事情,我们需要填写每个拦截功能的内容;其次,编写say_hello函数,并添加对say_hello函数的引用。00-1010因为say_hello扩展在每个生命周期阶段都不需要操作,所以我们只写info_func的内容。如上所述,当执行phpinfo()以显示扩展信息时,将自动调用该函数。写这个函数将使用四个函数:PHP _ info _ print _ table _ start()——来启动phpinfo表。没有参数。PHP _ info _ print _ table _ header()——输出表头。第一个参数是shaping,它指示标题中的列数,然后下面的参数是一个等于列数的(char*)类型参数,它指定显示的文本。PHP _ info _ print _ table _ row()——输出表格内容。第一个参数是shaping,它指示该行中的列数,然后下面的参数是一个等于列数的(char*)类型参数,它指定显示的文本。PHP _ info _ print _ table _ end()——结束phpinfo表。没有参数。阅读下一页的全文。

版权声明:谈PHP扩展——基础1/2页的开发是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。