<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></title> 
<link>http://jackxiang.com/index.php</link> 
<description><![CDATA[赢在IT，Playin' with IT,Focus on Killer Application,Marketing Meets Technology.]]></description> 
<language>zh-cn</language> 
<copyright><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></copyright>
<item>
<link>http://jackxiang.com/post//</link>
<title><![CDATA[Apache中php扩展实战 ------ 获得ip的来源地址]]></title> 
<author>jack &lt;xdy108@126.com&gt;</author>
<category><![CDATA[生活笔记]]></category>
<pubDate>Mon, 30 Jun 2008 09:31:27 +0000</pubDate> 
<guid>http://jackxiang.com/post//</guid> 
<description>
<![CDATA[ 
	<div class="entry-body"><div class="twikiToc"><ul><li><a href="http://my.huhoo.net/archives/2008/02/php_ip.html#1">1 前言</a> </li><li><a href="http://my.huhoo.net/archives/2008/02/php_ip.html#2">2 前提条件</a> </li><li><a href="http://my.huhoo.net/archives/2008/02/php_ip.html#3">3 流程及步骤</a> </li><li><a href="http://my.huhoo.net/archives/2008/02/php_ip.html#4">4 详细过程描述</a> <ul><li><a href="http://my.huhoo.net/archives/2008/02/php_ip.html#4_1">4.1 建立扩展目录</a> </li><li><a href="http://my.huhoo.net/archives/2008/02/php_ip.html#4_2_config_m4">4.2 描述及编辑config.m4</a> </li><li><a href="http://my.huhoo.net/archives/2008/02/php_ip.html#4_3_configure">4.3 创建configure文件</a> </li><li><a href="http://my.huhoo.net/archives/2008/02/php_ip.html#4_4_Makefile">4.4 创建Makefile文件</a> </li><li><a href="http://my.huhoo.net/archives/2008/02/php_ip.html#4_5">4.5 编译过程</a> </li><li><a href="http://my.huhoo.net/archives/2008/02/php_ip.html#4_6">4.6 安装扩展模块</a> </li><li><a href="http://my.huhoo.net/archives/2008/02/php_ip.html#4_7">4.7 运行测试</a> </li><li><a href="http://my.huhoo.net/archives/2008/02/php_ip.html#4_8_PHP">4.8 增添PHP扩展模块函数</a> </li></ul></li><li><a href="http://my.huhoo.net/archives/2008/02/php_ip.html#5_Bugs">5 Bugs</a> </li><li><a href="http://my.huhoo.net/archives/2008/02/php_ip.html#6">6 实例代码</a> </li><li><a href="http://my.huhoo.net/archives/2008/02/php_ip.html#7">7 总结</a> </li></ul></div></div><div id="more" class="entry-more"><p></p><h2><a name="1" href="http://my.huhoo.net/mt-static/html/editor-content.html?cs=utf-8"></a><a name="1_" href="http://my.huhoo.net/mt-static/html/editor-content.html?cs=utf-8"></a>1 前言 </h2><ul><li>主要目的让大家了解一下怎么做PHP语言的扩展，仍然以上次叙述的Perl的扩展的例子&mdash;&mdash;获得IP来源地址为例。 </li></ul><p></p><h2><a name="2" href="http://my.huhoo.net/mt-static/html/editor-content.html?cs=utf-8"></a><a name="2_" href="http://my.huhoo.net/mt-static/html/editor-content.html?cs=utf-8"></a>2 前提条件 </h2><ul><li>假设你已经拥有了 <strong>LAMP</strong> （Linux+Apache+Mysql+PHP的缩写），并假设其安装路径分别是： </li></ul><pre>Apache：/usr/local/apache<br />Mysql：/usr/local/mysql<br />PHP：/usr/local/php<br /></pre><ul><li>目前所叙述的实例可能与 mysql 没有太多的关系，所以无关紧要，但是 PHP 是必须安装的； </li><li>另外，需要 PHP 的源码，如果你没有，可以去 <a href="http://www.php.net/" target="_top">http://www.php.net</a> 获取 PHP 源码，其源码路径位： </li></ul><pre>PHPSrc：/usr/local/php/src<br /></pre><ul><li>末了说句，本实例完全在 Linux 64 位平台下演示，若有出入，可以随时联系笔者。 </li></ul><p></p><h2><a name="3" href="http://my.huhoo.net/mt-static/html/editor-content.html?cs=utf-8"></a><a name="3_" href="http://my.huhoo.net/mt-static/html/editor-content.html?cs=utf-8"></a>3 流程及步骤 </h2><ul><li>其实制作PHP扩展非常简单， <strong>ext_skel</strong> 命令的帮助已说明得非常详细，如下所示： </li></ul><pre>[Cnangel@localhost ~]$cd /usr/local/php/src/ext<br />[Cnangel@localhost ext]$ext_skel --help<br />./ext_skel --extname=module [--proto=file] [--stubs=file] [--xml[=file]]<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [--skel=dir] [--full-xml] [--no-help]<br /><br />&nbsp;&nbsp;--extname=module&nbsp;&nbsp; module is the name of your extension<br />&nbsp;&nbsp;--proto=file&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; file contains prototypes of functions to create<br />&nbsp;&nbsp;--stubs=file&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; generate only function stubs in file<br />&nbsp;&nbsp;--xml&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;generate xml documentation to be added to phpdoc-cvs<br />&nbsp;&nbsp;--skel=dir&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; path to the skeleton directory<br />&nbsp;&nbsp;--full-xml&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; generate xml documentation for a self-contained extension<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (not yet implemented)<br />&nbsp;&nbsp;--no-help&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;don't try to be nice and create comments in the code<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; and helper functions to test if the module compiled<br /></pre><ul><li>尝试着创建一个扩展 <strong>getaddress</strong> ： </li></ul><pre>[Cnangel@localhost ext]$ext_skel --extname=getaddress<br />Creating directory getaddress<br />Creating basic files: config.m4 config.w32 .cvsignore getaddress.c php_getaddress.h CREDITS EXPERIMENTAL tests/001.phpt getaddress.php [done].<br /><br />To use your new extension, you will have to execute the following steps:<br /><br />1.&nbsp;&nbsp;$ cd ..<br />2.&nbsp;&nbsp;$ vi ext/getaddress/config.m4<br />3.&nbsp;&nbsp;$ ./buildconf<br />4.&nbsp;&nbsp;$ ./configure --[with&#124;enable]-getaddress<br />5.&nbsp;&nbsp;$ make<br />6.&nbsp;&nbsp;$ ./php -f ext/getaddress/getaddress.php<br />7.&nbsp;&nbsp;$ vi ext/getaddress/getaddress.c<br />8.&nbsp;&nbsp;$ make<br /><br />Repeat steps 3-6 until you are satisfied with ext/getaddress/config.m4 and<br />step 6 confirms that your module is compiled into PHP. Then, start writing<br />code and repeat the last two steps as often as necessary.<br /></pre><ul><li>上面的后续的帮助步骤已经说得比较清楚，一共 <strong>8</strong> 个步骤； </li></ul><p></p><h2><a name="4" href="http://my.huhoo.net/mt-static/html/editor-content.html?cs=utf-8"></a><a name="4_" href="http://my.huhoo.net/mt-static/html/editor-content.html?cs=utf-8"></a>4 详细过程描述 </h2><h3><a name="4_1" href="http://my.huhoo.net/mt-static/html/editor-content.html?cs=utf-8"></a><a name="4_1_" href="http://my.huhoo.net/mt-static/html/editor-content.html?cs=utf-8"></a>4.1 建立扩展目录 </h3><ul><li>方便的 <strong>ext_skel</strong> 命令能帮助建立一个扩展模型 <strong>getaddress</strong> ，系统会自动建立一个 getaddress 目录，其文件会相应的生成在 getaddress 目录内； </li></ul><h3><a name="4_2_config_m4" href="http://my.huhoo.net/mt-static/html/editor-content.html?cs=utf-8"></a>4.2 描述及编辑config.m4 </h3><ul><li>用 <strong>ext_skel</strong> 建立的目录里面一般有 <strong>config.m4</strong> 这个文件，这里面有一些基础的宏定义： <ul><li><strong>dnl</strong> 是注释； </li><li><strong>PHP_ARG_WITH</strong> 或者 <strong>PHP_ARG_ENABLE</strong> 指定了PHP扩展模块的工作方式； </li><li><strong>PHP_REQUIRE_CXX</strong> 用于指定这个扩展用到了C++； </li><li><strong>PHP_ADD_INCLUDE</strong> 指定PHP扩展模块用到的头文件目录； </li><li><strong>PHP_CHECK_LIBRARY</strong> 指定PHP扩展模块PHP_ADD_LIBRARY_WITH_PATH定义以及库连接错误信息等； </li><li><strong>PHP_SUBST</strong> 用于说明这个扩展编译成动态链接库的形式； </li><li><strong>PHP_NEW_EXTENSION</strong> 用于指定有哪些源文件应该被编译,文件和文件之间用空格隔开； </li></ul></li><li>这里指定PHP扩展模块的工作方式为 <strong>PHP_ARG_ENABLE</strong> ，需要修改config.m4文件为： </li></ul><pre>[Cnangel@localhost getaddress]vim config.m4<br /></pre>找到里面有类似几行： <pre>&nbsp;&nbsp;&nbsp;&nbsp;dnl PHP_ARG_WITH(getaddress, for getaddress support,<br />&nbsp;&nbsp;&nbsp;&nbsp;dnl Make sure that the comment is aligned:<br />&nbsp;&nbsp;&nbsp;&nbsp;dnl [&nbsp;&nbsp;--with-getaddress&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Include getaddress support])<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;dnl Otherwise use enable:<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;dnl PHP_ARG_ENABLE(getaddress, whether to enable getaddress support,<br />&nbsp;&nbsp;&nbsp;&nbsp;dnl Make sure that the comment is aligned:<br />&nbsp;&nbsp;&nbsp;&nbsp;dnl [&nbsp;&nbsp;--enable-getaddress&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Enable getaddress support])<br /></pre>修改成： <pre>&nbsp;&nbsp;&nbsp;&nbsp;dnl PHP_ARG_WITH(getaddress, for getaddress support,<br />&nbsp;&nbsp;&nbsp;&nbsp;dnl Make sure that the comment is aligned:<br />&nbsp;&nbsp;&nbsp;&nbsp;dnl [&nbsp;&nbsp;--with-getaddress&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Include getaddress support])<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;dnl Otherwise use enable:<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;PHP_ARG_ENABLE(getaddress, whether to enable getaddress support,<br />&nbsp;&nbsp;&nbsp;&nbsp;Make sure that the comment is aligned:<br />&nbsp;&nbsp;&nbsp;&nbsp;[&nbsp;&nbsp;--enable-getaddress&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Enable getaddress support])<br /></pre><ul><li>除了修改 <strong>config.m4</strong> 外，还需要修改的文件有 <strong>getaddress.c</strong> 、 <strong>php_getaddress.h</strong> 两个文件，下面会说到该文件的修改。 </li></ul><h3><a name="4_3_configure" href="http://my.huhoo.net/mt-static/html/editor-content.html?cs=utf-8"></a><a name="4_3_configure_" href="http://my.huhoo.net/mt-static/html/editor-content.html?cs=utf-8"></a>4.3 创建configure文件 </h3><ul><li>源码修改：进入源代码根目录，使用工具 <strong>buildconf</strong> 创建 <strong>configure</strong> 文件，其命令如下： </li></ul><pre>[Cnangel@localhost getaddress]cd /usr/local/php/src<br />[Cnangel@localhost src]./buildconf<br /></pre><ul><li>扩展修改：进入扩展目录，使用工具 <strong>phpize</strong> 创建 <strong>configure</strong> 文件，其目录如下： </li></ul><pre>[Cnangel@localhost getaddress]/usr/local/php/bin/phpize<br />Configuring for:<br />PHP Api Version:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 20041225<br />Zend Module Api No:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;20060613<br />Zend Extension Api No:&nbsp;&nbsp; 220060519<br /></pre><h3><a name="4_4_Makefile" href="http://my.huhoo.net/mt-static/html/editor-content.html?cs=utf-8"></a><a name="4_4_Makefile_" href="http://my.huhoo.net/mt-static/html/editor-content.html?cs=utf-8"></a>4.4 创建Makefile文件 </h3><ul><li>上个步骤中创建了 <strong>configure</strong> 文件，记住，一般在类unix系统中， <strong>configure</strong> 文件是一个可执行文件，用来创建编译过程中所用到的make命令所需要的Makefile文件，其创建过程如下： </li></ul><pre>./configure --enable-getaddress --with-apxs=/usr/local/apache/bin/apxs --with-php-config=/usr/local/php/bin/php-config<br /></pre><ul><li>注意，如果你写的扩展与apache有关，则需要关联apxs，产生apache的modules。 </li></ul><h3><a name="4_5" href="http://my.huhoo.net/mt-static/html/editor-content.html?cs=utf-8"></a><a name="4_5_" href="http://my.huhoo.net/mt-static/html/editor-content.html?cs=utf-8"></a>4.5 编译过程 </h3><ul><li>编译过程是一个调试过程，出现错误了需要检查 <strong>config.m4</strong> 、 <strong>getaddress.c</strong> 、 <strong>php_getaddress.h</strong> 这几个文件是否编写正确，编译的过程十分简单，命令如下： </li></ul><pre>make<br /></pre><h3><a name="4_6" href="http://my.huhoo.net/mt-static/html/editor-content.html?cs=utf-8"></a><a name="4_6_" href="http://my.huhoo.net/mt-static/html/editor-content.html?cs=utf-8"></a>4.6 安装扩展模块 </h3><ul><li>安装扩展模块一般有两种安装，一种是直接： </li></ul><pre>make install<br /></pre><ul><li>结果会安装到： <strong>/usr/local/php/lib/php/extensions/no-debug-non-zts-20060613/</strong> 目录，然后在 php.ini 里面通过 <strong>extension_dir</strong> 将该目录设置为php的扩展目录，并在php.ini中打开这个扩展： </li></ul><pre>extension=getaddress.so<br /></pre><ul><li>另外一种是直接复制。一般经过编译过程这个步骤后，会在 getaddress 目录下生成一个目录： <strong>modules</strong> ，该目录下面有一个已经编译好的.so文件，如果是静态编译，可能是.a或.la；把该文件复制到一个目录下，比如： <strong><span style="color: #0000ff">/usr/loca/php/ext/</span></strong> ，然后直接调用函数 <strong>dl</strong> 来调用其 api。 </li></ul><p></p><h3><a name="4_7" href="http://my.huhoo.net/mt-static/html/editor-content.html?cs=utf-8"></a><a name="4_7_" href="http://my.huhoo.net/mt-static/html/editor-content.html?cs=utf-8"></a>4.7 运行测试 </h3><ul><li>getaddress 目录下有一个 <strong>getaddress.php</strong> 文件专门用来测试你的扩展模块是否正确运行，该文件即可以作为 CGI 来运行又可以当作脚本执行，命令如下： </li></ul><pre>[Cnangel@localhost getaddress]php -f getaddress.php<br />Functions available in the test extension:<br />confirm_getaddress_compiled<br /><br />Congratulations! You have successfully modified ext/getaddress/config.m4. Module getaddress is now compiled into PHP.<br /></pre><p></p><h3><a name="4_8_PHP" href="http://my.huhoo.net/mt-static/html/editor-content.html?cs=utf-8"></a><a name="4_8_PHP_" href="http://my.huhoo.net/mt-static/html/editor-content.html?cs=utf-8"></a>4.8 增添PHP扩展模块函数 </h3><ul><li>上述讲了这么多，这节才是最主要的。PHP扩展模块主要有三个方面的作用： <ol><li>增加PHP基础函数没有的功能或更加 OOP(Object Oriented Programming) 的思想供工程调用； </li><li>PHP的扩展一般是汇编、C/C++等编译性语言缩写，二进制运行消耗时间比解释性语言实现同样的功能少得多； </li><li>由于PHP扩展一般是二进制的，所以一般来说不开源，很方便的保护了版权，能够进行商业运用。 </li></ol></li><li>默认的 <strong>getaddress.c</strong> 中， <strong>zend_function_entry</strong> 是导出函数列表， <strong>zend_module_entry</strong> 描述了模块的信息。 </li><li>编写代码应该注意： <ol><li>如果是C++开发，记住把getaddress.c的后缀改为cpp，并用extern &quot;C&quot;来把c相关代码包起来； </li></ol></li></ul><p></p><h2><a name="5_Bugs" href="http://my.huhoo.net/mt-static/html/editor-content.html?cs=utf-8"></a>5 Bugs </h2><ul><li>在64位机器上和32位机器上会出现很大的差异，主要在QQWry.c文件； </li><li>多个引用php函数会出现corp dump情况，具体原因还未查清； </li></ul><p></p><h2><a name="6" href="http://my.huhoo.net/mt-static/html/editor-content.html?cs=utf-8"></a><a name="6_" href="http://my.huhoo.net/mt-static/html/editor-content.html?cs=utf-8"></a>6 实例代码 </h2><ul><li>注意，修复一处Bug：将 </li></ul><pre> Z_STRVAL_P(file) == NULL<br /></pre>代替 <pre> Z_STRLEN_P(file) == 0<br /></pre><ul><li>例子： </li><li><span style="display: inline" class="mt-enclosure mt-enclosure-file"><a href="http://my.huhoo.net/archives/upload/getaddress_php.tar.bz2">getaddress_php.tar.bz2</a></span></li><li><span style="display: inline" class="mt-enclosure mt-enclosure-file"><a href="http://my.huhoo.net/archives/upload/getaddress_php.tar.gz">getaddress_php.tar.gz</a></span></li></ul><p></p><h2><a name="7" href="http://my.huhoo.net/mt-static/html/editor-content.html?cs=utf-8"></a><a name="7_" href="http://my.huhoo.net/mt-static/html/editor-content.html?cs=utf-8"></a>7 总结 </h2><ul><li>由于作者对C指针运用不太熟练，所以在操作指针时，往往会出现corp dump，这方面有待加强； </li><li>就PHP扩展来说，涵盖的面比较广，需要丰富的知识面做铺垫才能做好一个优秀的扩展。 </li></ul></div><br/><br/>参考：<br/>http://tech.ddvip.com/2009-09/1252583445132022.html
]]>
</description>
</item><item>
<link>http://jackxiang.com/post//#blogcomment</link>
<title><![CDATA[[评论] Apache中php扩展实战 ------ 获得ip的来源地址]]></title> 
<author> &lt;user@domain.com&gt;</author>
<category><![CDATA[评论]]></category>
<pubDate>Thu, 01 Jan 1970 00:00:00 +0000</pubDate> 
<guid>http://jackxiang.com/post//#blogcomment</guid> 
<description>
<![CDATA[ 
	
]]>
</description>
</item>
</channel>
</rss>