Loading... <p>首先声明:我们要构建的是扩展或者模块名为hello_module.该模块提供一个方法:hello_word.</p> <h1><span style="font-size: 24px">1、php环境的搭建</span></h1> <blockquote><p>我们一般使用源码包编译安装,而不是binary包安装。因为<span style="font-family: Arial;line-height: 26px">使用PHP的二进制分发包安装有些冒险,这些版本倾向于忽略./configure的两个重要选项,它们在</span>开发<span style="font-family: Arial;line-height: 26px">过程中很便利:</span></p> <p><span style="font-family: Arial;line-height: 26px">第一个–enable-debug。这个选项将把附加的符号信息编译进PHP的执行文件,以便如果发生段错误,你能从中得到一个内核转储文件,使用gdb追踪并发现什么地方以及为什么会发生段错误。</span></p> <p><span style="font-family: Arial;line-height: 26px">另一个选项依赖于你的PHP版本。在PHP 4.3中该选项名为–enable-experimental-zts,在PHP 5及以后的版本中为–enable-maintainer-zts。这个选项使PHP以为自己执行于多线程环境,并且使你能捕获通常的程序错误,然而它们在非多线程环境中是无害的,却使你的扩展不可安全用于多线程环境。一旦你已经使用这些额外的选项编译了PHP并安装于你的开发</span>服务器<span style="font-family: Arial;line-height: 26px">(或者工作站)中,你就可以把你的第一个扩展加入其中了。</span></p> <p class="para" style="font-family: verdana, arial, helvetica, sans-serif"> Zend 引擎提供了一个内存管理器,有在扩展中跟踪内存泄漏的能力并提供详尽的调试信息。跟踪在默认情况下是被禁用的,同时也是线程安全的。要打开的话,应将 <span class="option configure" style="font-weight: bold">–enable-debug</span> 和 <em>–enable-maintainer-zts</em> 选项与其他常用选项一起传给 <var class="filename">configure</var>。要获得从源代码构建 PHP 的说明,请看位于 安装前需要考虑的事项 的说明。</p> <p class="para" style="font-family: verdana, arial, helvetica, sans-serif">典型的 <var class="filename">configure</var> 命令行可能看起来象这样:</p> <pre class="brush:python;toolbar:false">$ ./configure --prefix=/usr/local/php --enable-debug --enable-maintainer-zts --enable-cgi --enable-cli --with-mysql=/path/to/mysql</pre> <p> 1)一般可以把php安装在/usr/local/php目录下。</p> <p> 2)php的二进制可执行文件都在/usr/local/php/bin目录,包括php自带工具phpize.</p> <p> phpize实际上是个shell脚本,可以用vi phpize来查看其内容.</p> <p>注意:使用phpize需要安装<span style="font-family: verdana, arial, helvetica, sans-serif">autoconf 宏。</span></p> <p><span style="font-family: verdana, arial, helvetica, sans-serif"><var class="filename">因为config.m4</var></span><span style="font-family: verdana, arial, helvetica, sans-serif"> 文件使用 GNU </span><span class="command" style="font-family: verdana, arial, helvetica, sans-serif">autoconf</span><span style="font-family: verdana, arial, helvetica, sans-serif"> 语法编写。简而言之,就是用强大的宏语言增强的 shell 脚本。注释用字符串 </span><span style="font-family: verdana, arial, helvetica, sans-serif">dnl</span><span style="font-family: verdana, arial, helvetica, sans-serif"> 分隔,字符串则放在左右方括号中间(例如,</span><span style="font-family: verdana, arial, helvetica, sans-serif">[</span><span style="font-family: verdana, arial, helvetica, sans-serif"> 和 </span><span style="font-family: verdana, arial, helvetica, sans-serif">]</span><span style="font-family: verdana, arial, helvetica, sans-serif">)。字符串可按需要多次嵌套引用。完整的语法参考可参见位于http://www.gnu.org/software/autoconf/manual/</span></p> <p><span style="font-family: verdana, arial, helvetica, sans-serif"><strong>安装autoconf 宏最简单的方法:apt-get install autoconf</strong></span></p> </blockquote> <h1><span style="font-size: 24px"><span style="font-family: verdana, arial, helvetica, sans-serif">2、</span><span style="font-family: verdana, arial, helvetica, sans-serif">ext_skel脚本</span></span></h1> <blockquote><p class="para" style="font-family: verdana, arial, helvetica, sans-serif">PHP 扩展由几个文件组成,这些文件对所有扩展来说都是通用的。不同扩展之间,这些文件的很多细节是相似的,只是要费力去复制每个文件的内容。幸运的是,有脚本可以做所有的初始化工作,名为 <span class="command" style="font-weight: bold">ext_skel</span>,自 PHP 4.0 起与其一起分发。</p> <p class="para" style="font-family: verdana, arial, helvetica, sans-serif">不带参数运行 <span class="command" style="font-weight: bold">ext_skel</span> 在 PHP 5.3.2 中会产生以下输出:</p> <pre class="brush:python;toolbar:false">php-5.3.2/ext$ ./ext_skel ./ext_skel --extname=module [--proto=file] [--stubs=file] [--xml[=file]] [--skel=dir] [--full-xml] [--no-help] --extname=module module is the name of your extension --proto=file file contains prototypes of functions to create --stubs=file generate only function stubs in file --xml generate xml documentation to be added to phpdoc-cvs --skel=dir path to the skeleton directory --full-xml generate xml documentation for a self-contained extension (not yet implemented) --no-help don't try to be nice and create comments in the code and helper functions to test if the module compiled</pre> <p><span style="font-family: verdana, arial, helvetica, sans-serif"> 通常来说,开发一个新扩展时,仅需关注的参数是 </span><span style="font-family: verdana, arial, helvetica, sans-serif">–extname</span><span style="font-family: verdana, arial, helvetica, sans-serif"> 和 </span><span style="font-family: verdana, arial, helvetica, sans-serif">–no-help</span><span style="font-family: verdana, arial, helvetica, sans-serif">。除非已经熟悉扩展的结构,</span><span class="emphasis" style="font-family: verdana, arial, helvetica, sans-serif;font-weight: bold">不</span><span style="font-family: verdana, arial, helvetica, sans-serif">要想去使用 </span><span style="font-family: verdana, arial, helvetica, sans-serif">–no-help</span><span style="font-family: verdana, arial, helvetica, sans-serif">; 指定此参数会造成 </span><span class="command" style="font-family: verdana, arial, helvetica, sans-serif">ext_skel</span><span style="font-family: verdana, arial, helvetica, sans-serif"> 不会在生成的文件里省略很多有用的注释。</span></p> <p style="font-family: verdana, arial, helvetica, sans-serif"> 剩下的 <em>–extname</em> 会将扩展的名称传给 <span class="command" style="font-weight: bold">ext_skel</span>。"name" 是一个全为小写字母的标识符,仅包含字母和下划线,在 PHP 发行包的 <var class="filename">ext/</var> 文件夹下是唯一的。</p> <p class="para" style="font-family: verdana, arial, helvetica, sans-serif"><em> –proto</em>选项允许开发人员指定一个头文件,由此创建一系列 PHP 函数,表面上看就是要开发基于一个函数库的扩展,但对大多数头现代的文件来说很少能起作用。如果用 <var class="filename">zlib.h</var> 头文件来做测试,就会导致在 <span class="command" style="font-weight: bold">ext_skel</span> 的输出文件中存在大量的空的和无意义的原型文件。<em>–xml</em> 和 <em>–full-xml</em> 选项当前完全不起作用。<em>–skel</em> 选项可用于指定用一套修改过的框架文件来工作,这是本节范围之外的话题了。</p> </blockquote> <h1 style="margin: 0px;padding: 0px"><span style="font-family: verdana, arial, helvetica, sans-serif"><span style="font-size: 24px">3、扩展组成文件</span></span></h1> <blockquote><p><span style="font-family: verdana, arial, helvetica, sans-serif;font-size: 17px"><span style="font-size: 14px">不管是通过手工,通过</span></span></p> <p><span class="command">ext_skel</span> ,还是通过另外的扩展生成器,<span style="font-family: verdana, arial, helvetica, sans-serif">所有的扩展都会有以下个文件:</span></p> <p><span style="line-height: 28px;font-size: 17px"><span style="font-family: verdana, arial, helvetica, sans-serif"><strong>1) </strong></span></span></p> <p><span style="font-size: 17px"><strong>config.m4</strong></span><span style="line-height: 28px;font-size: 17px"><span style="font-family: verdana, arial, helvetica, sans-serif">:</span></span><span style="font-size: 17px">phpize用来准备<span style="font-family: verdana, arial, helvetica, sans-serif;font-size: 14px">构建系统哪些扩展的<span style="font-family: Arial;font-size: 17px">配置文件</span></span><var class="filename" style="font-family: verdana, arial, helvetica, sans-serif;font-size: 14px">configure</var><span style="font-family: verdana, arial, helvetica, sans-serif;font-size: 14px"> 选项 ,是UNIX 构建系统配置。</span></span><span style="font-size: 17px"><span style="font-family: verdana, arial, helvetica, sans-serif;font-size: 14px">对应的win系统是config.w32: http://www.php.net/manual/zh/internals2.buildsys.configunix.php</span></span></p> <p><strong>2) php_hello_module.h</strong></p> <p><span style="line-height: 25px"> :</span>包含引用的头文件<span style="font-family: verdana, arial, helvetica, sans-serif">当将扩展作为静态模块构建并放入PHP 二进制包时,构建系统要求用 </span><span style="font-family: verdana, arial, helvetica, sans-serif">php_</span><span style="font-family: verdana, arial, helvetica, sans-serif"> 加扩展的名称命名的 头文件包含一个对扩展模块结构的指针定义。就象其他头文件,此文件经常包含附加的宏、原型和全局量。当然你可以把头文件内容放在源文件<span style="font-family: Arial;line-height: 24px"><strong>hello_module.c顶部。分开只是让代码组织更清晰,而且是个很好的习惯。</strong></span></span></p> <p><span style="font-family: Arial;line-height: 24px"><strong>3) hello_module.c :</strong></span></p> <p>包含模块函数的源码文件 </p> <p><span style="font-family: verdana, arial, helvetica, sans-serif">扩展应包含任意数量的头文件、源文件、单元测试和其他支持文件,此四个文件仅够组成最小的扩展。hello_module扩展的文件列表如下所示:</span></p> <p><span style="font-family: verdana, arial, helvetica, sans-serif"></span></p> <pre class="brush:python;toolbar:false">ext/ hello_module/ config.m4 config.w32 CREDITS EXPERIMENTAL php_hello_module.h hello_module.c tests/ 001.phpt</pre> </blockquote> <h1>4、<span style="font-family: verdana, arial, helvetica, sans-serif">与 UNIX 构建系统交互</span><span style="font-family: verdana, arial, helvetica, sans-serif">: config.m4</span></h1> <blockquote><p style="text-align:left"> config.m4文件负责在配置时解析configure的命令行选项。这就是说它将检查所需的外部文件并且要做一些类似配置与安装的任务。<var class="filename">config.m4</var> 文件告诉 UNIX 构建系统哪些扩展 <var class="filename">configure</var> 选项是支持的,你需要哪些扩展库,以及哪些源文件要编译成它的一部分。对所有经常使用的 autoconf 宏,包括 PHP 特定的及 autoconf 内建的,</p> <pre class="brush:python;toolbar:false">config.m4 文件举例 dnl $Id$ dnl config.m4 for extension example PHP_ARG_WITH(example, for example support, [ --with-example[=FILE] Include example support. File is the optional path to example-config]) PHP_ARG_ENABLE(example-debug, whether to enable debugging support in example, [ --enable-example-debug example: Enable debugging support in example], no, no) PHP_ARG_WITH(example-extra, for extra libraries for example, [ --with-example-extra=DIR example: Location of extra libraries for example], no, no) dnl 检测扩展是否已启用 if test "$PHP_EXAMPLE" != "no"; then dnl 检测 example-config。首先尝试所给出的路径,然后在 $PATH 中寻找 AC_MSG_CHECKING([for example-config]) EXAMPLE_CONFIG="example-config" if test "$PHP_EXAMPLE" != "yes"; then EXAMPLE_PATH=$PHP_EXAMPLE else EXAMPLE_PATH=`$php_shtool path $EXAMPLE_CONFIG` fi dnl 如果找到可用的 example-config,就使用它 if test -f "$EXAMPLE_PATH" && test -x "$EXAMPLE_PATH" && $EXAMPLE_PATH --version > /dev/null 2>&1; then AC_MSG_RESULT([$EXAMPLE_PATH]) EXAMPLE_LIB_NAME=`$EXAMPLE_PATH --libname` EXAMPLE_INCDIRS=`$EXAMPLE_PATH --incdirs` EXAMPLE_LIBS=`$EXAMPLE_PATH --libs` dnl 检测扩展库是否工作正常 PHP_CHECK_LIBRARY($EXAMPLE_LIB_NAME, example_critical_function, [ dnl 添加所需的 include 目录 PHP_EVAL_INCLINE($EXAMPLE_INCDIRS) dnl 添加所需的扩展库及扩展库所在目录 PHP_EVAL_LIBLINE($EXAMPLE_LIBS, EXAMPLE_SHARED_LIBADD) ],[ dnl 跳出 AC_MSG_ERROR([example library not found. Check config.log for more information.]) ],[$EXAMPLE_LIBS] ) else dnl 没有可用的 example-config,跳出 AC_MSG_RESULT([not found]) AC_MSG_ERROR([Please check your example installation.]) fi dnl 检测是否启用调试 if test "$PHP_EXAMPLE_DEBUG" != "no"; then dnl 是,则设置 C 语言宏指令 AC_DEFINE(USE_EXAMPLE_DEBUG,1,[Include debugging support in example]) fi dnl 检测额外的支持 if test "$PHP_EXAMPLE_EXTRA" != "no"; then if test "$PHP_EXAMPLE_EXTRA" == "yes"; then AC_MSG_ERROR([You must specify a path when using --with-example-extra]) fi PHP_CHECK_LIBRARY(example-extra, example_critical_extra_function, [ dnl 添加所需路径 PHP_ADD_INCLUDE($PHP_EXAMPLE_EXTRA/include) PHP_ADD_LIBRARY_WITH_PATH(example-extra, $PHP_EXAMPLE_EXTRA/lib, EXAMPLE_SHARED_LIBADD) AC_DEFINE(HAVE_EXAMPLEEXTRALIB,1,[Whether example-extra support is present and requested]) EXAMPLE_SOURCES="$EXAMPLE_SOURCES example_extra.c" ],[ AC_MSG_ERROR([example-extra lib not found. See config.log for more information.]) ],[-L$PHP_EXAMPLE_EXTRA/lib] ) fi dnl 最后,将扩展及其所需文件等信息传给构建系统 PHP_NEW_EXTENSION(example, example.c $EXAMPLE_SOURCES, $ext_shared) PHP_SUBST(EXAMPLE_SHARED_LIBADD) fi</pre> <h3 class="title" style="margin: 0px;padding: 0px;font-family: verdana, arial, helvetica, sans-serif;font-size: 15px"> <p style="text-align:left">注意:凡是带有dnl前缀的都是注释,注释是不被解析的。</p> </h3> </blockquote> <blockquote><h2 style="margin: 0px;padding: 0px">4.1 PHP_ARG_*: 赋予用户可选项</h2> </blockquote> <p><span style="font-family: verdana, arial, helvetica, sans-serif;font-size: 17px"><span style="font-size: 14px"></span></span></p> <blockquote><p><span style="font-family: verdana, arial, helvetica, sans-serif"> 在以上的 </span></p> <p><var class="filename" style="font-family: verdana, arial, helvetica, sans-serif">config.m4</var><span style="font-family: verdana, arial, helvetica, sans-serif"> 例子中,两条注释后,最先见到的 3 行代码,使用了 </span><span class="function" style="font-family: verdana, arial, helvetica, sans-serif"><strong>PHP_ARG_WITH()</strong></span><span style="font-family: verdana, arial, helvetica, sans-serif"> 和 </span><span class="function" style="font-family: verdana, arial, helvetica, sans-serif"><strong>PHP_ARG_ENABLE()</strong></span><span style="font-family: verdana, arial, helvetica, sans-serif">。这些给 </span><span class="command" style="font-family: verdana, arial, helvetica, sans-serif">configure</span><span style="font-family: verdana, arial, helvetica, sans-serif"> 提供了可选项,和在运行 </span><span class="command" style="font-family: verdana, arial, helvetica, sans-serif">./configure –help</span><span style="font-family: verdana, arial, helvetica, sans-serif"> 时显示的帮助文本。就象名称所暗示的,其两者的不同点在于是创建 </span><span class="option configure" style="font-family: verdana, arial, helvetica, sans-serif">–with-*</span><span style="font-family: verdana, arial, helvetica, sans-serif"> 选项还是 </span><span class="option configure" style="font-family: verdana, arial, helvetica, sans-serif">–enable-*</span><span style="font-family: verdana, arial, helvetica, sans-serif"> 选项。每个扩展应提供至少一个以上的选项以及扩展名称,以便用户可选择是否将扩展构建至 PHP 中。按惯例,</span><span class="function" style="font-family: verdana, arial, helvetica, sans-serif"><strong>PHP_ARG_WITH()</strong></span><span style="font-family: verdana, arial, helvetica, sans-serif"> 用于取得参数的选项,例如扩展所需库或程序的位置;而 </span><span class="function" style="font-family: verdana, arial, helvetica, sans-serif"><strong>PHP_ARG_ENABLE()</strong></span><span style="font-family: verdana, arial, helvetica, sans-serif"> 用于代表简单标志的选项。</span></p> <p style="text-align:left">不管你使用哪一个指令,你都应该注释掉另外一个。也就是说,如果你使用了–enable-my_module,那就应该去掉–with-my_module。反之亦然。</p> <p>configue使用例子:./configure –enable-hello_module</p> <p>则将</p> <pre class="brush:python;toolbar:false">dnl PHP_ARG_ENABLE(hello_module, whether to enablehello_module support, dnl Make sure that the comment is aligned: dnl [ --enable-hello_module Enablehello_module support])</pre> <p>修改成</p> <pre class="brush:python;toolbar:false">PHP_ARG_ENABLE(hello_module, whether to enablehello_module support, [ --enable-hello_module Enablehello_module support])</pre> <h2 style="margin: 0px;padding: 0px">4.2 处理用户选择</h2> <p class="para" style="font-family: verdana, arial, helvetica, sans-serif"><var class="filename"> config.m4</var></p> <p> 可给用户提供一些做什么的选择,现在就是做出选择的时候了。在上例中,三个选项在未指定时显然默认为 "no"。习惯上,最好用此值作为用于启用扩展的选项的默认值,为了扩展与 PHP 分开构建则用 <span class="command" style="font-weight: bold">phpize</span> 覆盖此值,而要构建在 PHP 中时则不应被默认值将扩展空间弄乱。处理这三个选项的代码要复杂得多。</p> <h4 class="title" style="margin: 0px;padding: 0px;background-color: transparent">处理 –with-example[=FILE] 选项</h4> <p class="para"> 首先检测是否设置了 <span class="option configure" style="font-weight: bold">–with-example[=FILE]</span> 选项。如此选项未被指定,或使用否定的格式(<span class="option configure" style="font-weight: bold">–without-example</span> ),或赋值为 "no" 时,它会控制整个扩展的含有物其他任何事情都不会发生。在上面的例子中所指定的值为 <em>/some/library/path/example-config</em>,所以第一个 test 成功了。</p> <p class="para">接下来,代码调用 <span class="function"><strong>AC_MSG_CHECKING()</strong></span>,这是一个 <span class="command" style="font-weight: bold">autoconf</span> 宏,输出一行标准的如 "checking for …" 的信息,并检测用户假定的 <span class="command" style="font-weight: bold">example-config</span> 是否是一个明确的路径。在这个例子中,<em>PHP_EXAMPLE</em> 所取到的值为 <em>/some/library/path/example-config</em>,现已复制到 EXAMPLE_PATH 变量中了。只有用户指定了 <span class="option configure" style="font-weight: bold">–with-example</span> ,才会执行代码 <span class="command" style="font-weight: bold">$php_shtool path $EXAMPLE_CONFIG</span>,尝试使用用户当前的 <em>PATH</em> 环境变量推测 <span class="command" style="font-weight: bold">example-config</span> 的位置。无论如何,下一步都是检测所选的<em>EXAMPLE_PATH</em> 是否是正常文件,是否可执行,及是否执行成功。如成功,则调用 <span class="function"><strong>AC_MSG_RESULT()</strong></span>,结束由 <span class="function"><strong>AC_MSG_CHECKING()</strong></span> 开始的输出行。否则,调用 <span class="function"><strong>AC_MSG_ERROR()</strong></span>,打印所给的信息并立即中断执行 <span class="command" style="font-weight: bold">configure</span>。</p> <p class="para">代码现在执行几次 <span class="command" style="font-weight: bold">example-config</span> 以确定一些站点特定的配置信息。下一步调用的是 <span class="function"><strong>PHP_CHECK_LIBRARY()</strong></span>,这是 PHP 构建系统提供的一个宏,包装了 <span class="command" style="font-weight: bold">autoconf</span> 的 <span class="function"><strong>AC_CHECK_LIB()</strong></span> 函数。<span class="function"><strong>PHP_CHECK_LIBRARY()</strong></span> 尝试编译、链接和执行程序,在第一个参数指定的库中调用由第二个参数指定的符号,使用第五个参数给出的字符串作为额外的链接选项。如果尝试成功了,则运行第三个参数所给出的脚本。此脚本从 <span class="command" style="font-weight: bold">example-config</span> 所提供的原始的选项字符串中取出头文件路径、库文件路径和库名称,告诉 PHP 构建系统。如果尝试失败,脚本则运行第四个参数中的脚本。此时调用 <span class="function"><strong>AC_MSG_ERROR()</strong></span> 来中断程序执行。</p> <h4 class="title" style="margin: 0px;padding: 0px;background-color: transparent">处理 –enable-example-debug 选项</h4> <p class="para"> 处理 <span class="option configure" style="font-weight: bold">–enable-example-debug</span> 很简单。只简单地检测其真实值。如果检测成功,则调用 <span class="function"><strong>AC_DEFINE()</strong></span> 使 C 语言宏指令 <em>USE_EXAMPLE_DEBUG</em> 可用于扩展的源代码。第三个参数是给 <var class="filename">config.h</var> 的注释字符串,通常可放心的留空。</p> <h4 class="title" style="margin: 0px;padding: 0px;background-color: transparent">处理 –with-example-extra=DIR 选项</h4> <p class="para"> 对于此例子来说,由 <span class="option configure" style="font-weight: bold">–with-example-extra=DIR</span> 选项所请求的假定的“额外”功能操作不会与假定的 <span class="command" style="font-weight: bold">example-config</span> 程序共享,也没有默认的搜索路径。因此,用户需要在所需的库之前提供设置程序。有点不象现实中的扩展,在这里的设置仅仅起说明性的作用。</p> <p class="para">代码开始用已熟知的方式来检测 <em>PHP_EXAMPLE_EXTRA</em> 的真实值。如果所提供的为否定形式,则不会进行其他处理,用户也不会请求额外的功能。如果所提供的为未提供参数的肯定形式,则调用 <span class="function"><strong>AC_MSG_ERROR()</strong></span> 中止处理。下一步则再次调用<span class="function"><strong>PHP_CHECK_LIBRARY()</strong></span>。这一次,因为没有提供预定义编译选项,<span class="function"><strong>PHP_ADD_INCLUDE()</strong></span> 和 <span class="function"><strong>PHP_ADD_LIBRARY_WITH_PATH()</strong></span> 用于构建额外功能所需的头文件路径、库文件路径和库标志。也调用 <span class="function"><strong>AC_DEFINE()</strong></span> 来指示所请求的额外功能代码是可用的,设置变量来告诉以后的代码,有额外的源代码要构建。如果检测失败,则调用所熟悉的 <span class="function"><strong>AC_MSG_ERROR()</strong></span>。另一种不同的处理失败的方式是更换为调用 <span class="function"><strong>AC_MSG_WARNING()</strong></span>,例如:</p> <h2 style="margin: 0px;padding: 0px">4.3 <span style="font-family: verdana, arial, helvetica, sans-serif;line-height: 24px;text-indent: 6px">PHP_NEW_EXTENSION宏</span></h2> <p style="text-align:left"> 默认情况下,通过ext_skel创建的config.m4都能接受指令,并且会自动启用该扩展。启用该扩展是通过PHP_EXTENSION这个宏进行的。如果你要改变一下默认的情况,想让用户明确的使用 –enable-my_module或 –with-my_module指令来把扩展包含在PHP二进制文件当中,那么将 “if test "$PHP_MY_MODULE" != "no"”改为“if test "$PHP_MY_MODULE" == "yes"”即可。</p> <pre class="brush:python;toolbar:false">if test "$PHP_MY_MODULE" == "yes"; thendnl PHP_EXTENSION(hello_module, $ext_shared) fi</pre> <p style="text-align:left">这样就会导致在每次重新配置和编译PHP时都要求用户使用 –enable-my_module指令。 </p> <p class="para" style="font-family: verdana, arial, helvetica, sans-serif"><span class="function" style="line-height: 25px;text-indent: 9px"><strong>PHP_NEW_EXTENSION()</strong></span></p> <p><span style="line-height: 25px;text-indent: 9px"> 就是宏</span>告诉构建系统去构建扩展本身和被其用到的文件。</p> <p class="para" style="font-family: verdana, arial, helvetica, sans-serif"><span class="function" style="line-height: 25px;text-indent: 9px"><strong>PHP_NEW_EXTENSION()参数:</strong></span></p> <p class="para" style="font-family: verdana, arial, helvetica, sans-serif"> <strong>第一个参数是扩展的名称</strong>,和包含它的目录同名。</p> <p class="para" style="font-family: verdana, arial, helvetica, sans-serif"><strong> 第二个参数是做为扩展的一部分的所有源文件的列表</strong></p> <p>。参见 <span class="function"><strong>PHP_ADD_BUILD_DIR()</strong></span> 以获取将在子目录中源文件添加到构建过程的相关信息。</p> <p class="para" style="font-family: verdana, arial, helvetica, sans-serif"> <strong>第三个参数总是 <em>$ext_shared</em></strong>, 当为了 <span class="option configure" style="font-weight: bold">–with-example[=FILE]</span> 而调用 <span class="function"><strong>PHP_ARG_WITH()</strong></span>时,由 <span class="command" style="font-weight: bold">configure</span> 决定参数的值。</p> <p class="para" style="font-family: verdana, arial, helvetica, sans-serif"> 第四个参数指定一个“SAPI 类”,仅用于专门需要 CGI 或 CLI SAPI 的扩展。其他情况下应留空。</p> <p class="para" style="font-family: verdana, arial, helvetica, sans-serif"> 第五个参数指定了构建时要加入 <em>CFLAGS</em> 的标志列表。</p> <p class="para" style="font-family: verdana, arial, helvetica, sans-serif"> 第六个参数是一个布尔值,为 "yes" 时会强迫整个扩展使用 <em>$CXX</em> 代替 <em>$CC</em> 来构建。第三个以后的所有参数都是可选的。最后,调用 <span class="function"><strong>PHP_SUBST()</strong></span> 来启用扩展的共享构建。</p> <p> 例如我们要构建扩展是hello_module</p> <pre class="brush:python;toolbar:false">dnl $Id$ dnl config.m4 for extension hello PHP_ARG_ENABLE(hello, whether to enable hello support, [ --enable-hello Enable hello support]) if test "$PHP_HELLO" != "no"; then PHP_NEW_EXTENSION(hello_module, hello_module.c, $ext_shared) fi</pre> </blockquote> <h1><span style="font-family: verdana, arial, helvetica, sans-serif"><span style="text-indent: 13px"><span style="font-size: 24px">5、扩展模块代码的</span></span></span></h1> <blockquote><h3 style="margin: 0px;padding: 0px">模块结构</h3> <p style="text-align:left">所有的PHP模块通常都包含以下几个部分:</p> <p style="text-align:left">· 包含头文件(引入所需要的宏、API定义等);</p> <p style="text-align:left">· 声明导出函数(用于Zend函数块的声明);</p> <p style="text-align:left">· 声明Zend函数块;</p> <p style="text-align:left">· 声明Zend模块;</p> <p style="text-align:left">· 实现<strong>get_module()</strong>函数;</p> <p style="text-align:left">· 实现导出函数。</p> <p style="text-align:left">详解请看:</p> <h3 style="margin: 0px;padding: 0px"><span class="link_title">PHP扩展代码结构详解</span></h3> </blockquote> <h1><span style="font-family: verdana, arial, helvetica, sans-serif;text-indent: 13px"><span style="font-size: 24px">6、创建扩展的详细步骤</span></span></h1> <blockquote><p>我们创建扩展最好放在php的源码包的ext目录下。如/opt/php-5.3.2/ext/下</p> <p><strong>1) ext_skel来建立一个php扩展的一个框架</strong></p> <p>root@ubuntu:/# cd /opt/php-5.3.2/ext/</p> <p>root@ubuntu:opt/php-5.3.2/ext/]# ./ext_skel –extname=hello_module</p> <p>执行了这个步骤以后看到这样的结果: </p> <pre class="brush:python;toolbar:false">Creating directory hello_module Creating basic files: config.m4 config.w32 .cvsignore hello_module.c php_hello_module.h CREDITS EXPERIMENTAL tests/001.phpt hello_module.php [done]. To use your new extension, you will have to execute the following steps: 1. $ cd .. 2. $ vi ext/hello_module/config.m4 3. $ ./buildconf 4. $ ./configure --[with|enable]-hello_module 5. $ make 6. $ ./php -f ext/hello_module/hello_module.php 7. $ vi ext/hello_module/hello_module.c 8. $ make Repeat steps 3-6 until you are satisfied with ext/hello_module/config.m4 and step 6 confirms that your module is compiled into PHP. Then, start writing code and repeat the last two steps as often as necessary.</pre> <p>在这个目录下生成一个目录叫hello_module</p> <p>进入这里面我们看看</p> <pre class="brush:python;toolbar:false">root@ubuntu:opt/php-5.3.2/ext# #cd hello_module root@ubuntu:/opt/php-5.3.2/ext/hello_module# ls config.m4 config.w32 CREDITS EXPERIMENTAL hello_module.c hello_module.php php_hello_module.h tests</pre> <p>然后我们要修改文件顺序是</p> <pre class="brush:python;toolbar:false">configue.m4 hello_module.c php_hello_module.h</pre> <p><strong>2)编辑config.m4文件,我们使用enable-hello_module选项:</strong></p> <pre class="brush:python;toolbar:false">dnl PHP_ARG_ENABLE(hello_module, whether to enablehello_module support, dnl Make sure that the comment is aligned: dnl [ --enable-hello_module Enable hello_module support])</pre> <p>修改成</p> <pre class="brush:python;toolbar:false">PHP_ARG_ENABLE(hello_module, whether to enable hello_module support, [ --enable-hello_module Enable hello_module support])</pre> <p><strong>3)vi hello_module.c</strong></p> <p>主要是给模块添加函数:</p> <pre class="brush:python;toolbar:false"> /* Every user visible function must have an entry in my_module_functions[].*/ function_entry hello_module_functions[] = { PHP_FE(hello_world, NULL) /* 添加着一行代码 */ PHP_FE(confirm_my_module_compiled, NULL) /* For testing, remove later. */ {NULL, NULL, NULL} /* Must be the last line in my_module_functions[] */ };</pre> <p>在文件的最后添加下列代码</p> <p> 定义函数:</p> <pre class="brush:python;toolbar:false">PHP_FUNCTION(hello_world) { zend_printf("hello sdomain!"); }</pre> <p><strong>4)修改php_hello_module.h</strong></p> <p>在PHP_FUNCTION(confirm_my_module_compiled ); /* For testing, remove later. */ 这行的下面添加一行:</p> <p>PHP_FUNCTION(hello_world); /* 函数的声明 */</p> <p><strong>5) 执行phpize并编译</strong></p> <p> root@ubuntu:/opt/php-5.3.2/ext/hello_module# /usr/local/php/bin/phpize</p> <p> 执行以后会看到下面的</p> <p> Configuring for:<br /> PHP Api Version: 20090626<br /> Zend Module Api No: 20090626<br /> Zend Extension Api No: 220090626</p> <p>然后执行:</p> <p>root@ubuntu:/opt/php-5.3.2/ext/hello_module#./configure –enable-hello_module –with-php-config=/usr/local/php/bin/php-config</p> <p>root@ubuntu:/opt/php-5.3.2/ext/hello_module# make</p> <p>这个时候会在当前的目录下生成一个目录叫modules先存放着hello_module.so文件</p> <p>cp modules/hello_module.so /usr/local/php/ext/</p> <p>然后再把<span style="font-family: Arial;line-height: 25px">hello_module.so</span>文件拷到php.ini里面的extension_dir所指定的位置</p> <p><strong>6)开启扩展</strong></p> <p>php.ini文件中打开这个扩展</p> <p>extension=hello_module.so</p> <p>重新起动apache</p> <p>用phpinfo来察看一下ok了</p> </blockquote> <p>我们看看安装php memcached的扩展:</p> <p><span style="font-family: 微软雅黑, Arial, 宋体;line-height: 1.8em;text-indent: 2em">安装分两步</span></p> <p><span style="font-family: 微软雅黑, Arial, 宋体;line-height: 1.8em;text-indent: 2em">安装libmemcached,目标是so和header文件</span></p> <p><span style="font-family: 微软雅黑, Arial, 宋体;line-height: 1.8em;text-indent: 2em">安装memcached php extensions</span></p> <p><span style="font-family: 微软雅黑, Arial, 宋体;line-height: 1.8em;text-indent: 2em">libmemcaced 分为两大版本0.x和1.x, 1.x的版本从2011-09-28开始,编译很麻烦,需要gcc4.0以上的专门配置,compile无比慢. 0.x版本就简单很多,最高版本是0.53,所以选择安装0.53</span></p> <p><span style="font-family: 微软雅黑, Arial, 宋体;line-height: 1.8em;text-indent: 2em">极品总是成对出现,php的memcahed也从2.1.0开始,要求libmemcached 必须是1.0.x版本</span></p> <p><span style="font-family: 微软雅黑, Arial, 宋体;line-height: 1.8em;text-indent: 2em"><strong>安装libmemcached</strong></span></p> <p><span style="font-family: 微软雅黑, Arial, 宋体;line-height: 1.8em;text-indent: 2em"><strong>下载:https://launchpad.net/libmemcached/+download<br /></strong></span></p> <p><span style="font-family: 微软雅黑, Arial, 宋体;line-height: 1.8em;text-indent: 2em">wget https://launchpadlibrarian.net/135986673/libmemcached-1.0.17.tar.gz</span></p> <p><span style="font-family: 微软雅黑, Arial, 宋体;line-height: 1.8em;text-indent: 2em">tar xvfz libmemcached<span style="line-height: 25.200000762939453px">-1.0.17</span>.tar.gz</span></p> <p><span style="font-family: 微软雅黑, Arial, 宋体;line-height: 1.8em;text-indent: 2em">cd<span style="line-height: 25.200000762939453px">libmemcached</span><span style="line-height: 25.200000762939453px">-1.0.17</span></span></p> <p><span style="font-family: 微软雅黑, Arial, 宋体;line-height: 1.8em;text-indent: 2em">./configure –prefix=/usr/local/libmemcached</span></p> <p><span style="font-family: 微软雅黑, Arial, 宋体;line-height: 1.8em;text-indent: 2em">make && make install</span></p> <p><span style="font-family: 微软雅黑, Arial, 宋体;line-height: 1.8em;text-indent: 2em"><strong>安装php扩展,</strong></span></p> <p><span style="font-family: 微软雅黑, Arial, 宋体;line-height: 1.8em;text-indent: 2em">使用php官网的源码安装</span></p> <p><span style="font-family: 微软雅黑, Arial, 宋体;line-height: 1.8em;text-indent: 2em">wget http://pecl.php.net/get/memcached-2.0.0.tgz</span></p> <p><span style="font-family: 微软雅黑, Arial, 宋体;line-height: 1.8em;text-indent: 2em">(https://github.com/php-memcached-dev/php-memcached)</span></p> <p><span style="font-family: 微软雅黑, Arial, 宋体;line-height: 1.8em;text-indent: 2em">tar zvxf memcached-2.0.0.tgz</span></p> <p><span style="font-family: 微软雅黑, Arial, 宋体;line-height: 1.8em;text-indent: 2em">cd memcached-2.0.0/</span></p> <p><span style="font-family: 微软雅黑, Arial, 宋体;line-height: 1.8em;text-indent: 2em">ls ,你会看到只是源码。然后:</span></p> <p><span style="font-family: 微软雅黑, Arial, 宋体;line-height: 1.8em;text-indent: 2em">/usr/local/php/bin/phpize</span></p> <p><span style="font-family: 微软雅黑, Arial, 宋体;line-height: 1.8em;text-indent: 2em">./configure –enable-memcached –with-php-config=/usr/local/php/bin/php-config –with-libmemcached-dir=/usr/local/libmemcached/</span></p> <p><span style="font-family: 微软雅黑, Arial, 宋体;line-height: 1.8em;text-indent: 2em">make && make install</span></p> <p><span style="font-family: 微软雅黑, Arial, 宋体;line-height: 1.8em;text-indent: 2em">make install 是 把memcached.so 安装到 ${php install dir}/extensions/no-debug-non-zts-20090626/,这个目录随着php的版本不同而不同</span></p> <p><span style="font-family: 微软雅黑, Arial, 宋体;line-height: 1.8em;text-indent: 2em">最后一步,修改php.ini,加上 extension=memcached.so</span></p> <p>(<strong>使用bin/php –ini 查看php.ini所在目录)</strong></p> 最后修改:2021 年 12 月 10 日 10 : 53 AM © 允许规范转载 赞赏 如果觉得我的文章对你有用,请随意赞赏 赞赏作者 支付宝微信