<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>扩展 on 勇气</title><link>https://courages.us/tag/%E6%89%A9%E5%B1%95/</link><description>Recent content in 扩展 on 勇气</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Sun, 14 Jun 2015 12:55:24 +0800</lastBuildDate><atom:link href="https://courages.us/tag/%E6%89%A9%E5%B1%95/index.xml" rel="self" type="application/rss+xml"/><item><title>PHP 扩展开发之C</title><link>https://courages.us/php-%E6%89%A9%E5%B1%95%E5%BC%80%E5%8F%91%E4%B9%8Bc/</link><pubDate>Thu, 11 Jun 2015 23:06:33 +0800</pubDate><guid>https://courages.us/php-%E6%89%A9%E5%B1%95%E5%BC%80%E5%8F%91%E4%B9%8Bc/</guid><description>&lt;p&gt;前面介绍了使用&lt;a class="link" href="https://courages.us/php-%e6%89%a9%e5%b1%95%e5%bc%80%e5%8f%91%e4%b9%8bzephir/" target="_blank" rel="noopener"&#10; &gt;Zephir来开发PHP扩展&lt;/a&gt;，将PHP代码转为扩展，以提升性能，保护代码。目前更多的扩展都是采用C/C++开发的，最近在项目开发中，需要在这些已有的PHP扩展上开发，也只能用C/C++来开发了。&lt;/p&gt;&#10;&lt;p&gt;首先去&lt;a class="link" href="http://www.php.net" target="_blank" rel="noopener"&#10; &gt;PHP官网&lt;/a&gt;下载对应版本的PHP源码，解压并进入对应的目录。&lt;br&gt;&#10;创建扩展courages：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;vagrant@vagrant-centos64 ext&lt;span style="color:#f92672"&gt;]&lt;/span&gt;$ ./ext_skel&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;./ext_skel --extname&lt;span style="color:#f92672"&gt;=&lt;/span&gt;module &lt;span style="color:#f92672"&gt;[&lt;/span&gt;--proto&lt;span style="color:#f92672"&gt;=&lt;/span&gt;file&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt;--stubs&lt;span style="color:#f92672"&gt;=&lt;/span&gt;file&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt;--xml&lt;span style="color:#f92672"&gt;[=&lt;/span&gt;file&lt;span style="color:#f92672"&gt;]]&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt;--skel&lt;span style="color:#f92672"&gt;=&lt;/span&gt;dir&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt;--full-xml&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt;--no-help&lt;span style="color:#f92672"&gt;]&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --extname&lt;span style="color:#f92672"&gt;=&lt;/span&gt;module module is the name of your extension&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --proto&lt;span style="color:#f92672"&gt;=&lt;/span&gt;file file contains prototypes of functions to create&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --stubs&lt;span style="color:#f92672"&gt;=&lt;/span&gt;file generate only &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; stubs in file&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --xml generate xml documentation to be added to phpdoc-cvs&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --skel&lt;span style="color:#f92672"&gt;=&lt;/span&gt;dir path to the skeleton directory&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --full-xml generate xml documentation &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; a self-contained extension&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;(&lt;/span&gt;not yet implemented&lt;span style="color:#f92672"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --no-help don&lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;&lt;/span&gt;t try to be nice and create comments in the code&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; and helper functions to test &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; the module compiled&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;vagrant@vagrant-centos64 ext&lt;span style="color:#f92672"&gt;]&lt;/span&gt;$ ./ext_skel --extname&lt;span style="color:#f92672"&gt;=&lt;/span&gt;courages&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Creating directory courages&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Creating basic files: config.m4 config.w32 .svnignore courages.c php_courages.h CREDITS EXPERIMENTAL tests/001.phpt courages.php &lt;span style="color:#f92672"&gt;[&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;done&lt;/span&gt;&lt;span style="color:#f92672"&gt;]&lt;/span&gt;.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;To use your new extension, you will have to execute the following steps:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;1. $ cd ..&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;2. $ vi ext/courages/config.m4&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;3. $ ./buildconf&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;4. $ ./configure --&lt;span style="color:#f92672"&gt;[&lt;/span&gt;with|enable&lt;span style="color:#f92672"&gt;]&lt;/span&gt;-courages&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;5. $ make&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;6. $ ./sapi/cli/php -f ext/courages/courages.php&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;7. $ vi ext/courages/courages.c&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;8. $ make&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Repeat steps 3-6 &lt;span style="color:#66d9ef"&gt;until&lt;/span&gt; you are satisfied with ext/courages/config.m4 and&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;step &lt;span style="color:#ae81ff"&gt;6&lt;/span&gt; confirms that your module is compiled into PHP. Then, start writing&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;code and repeat the last two steps as often as necessary.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这里的步骤说的很清楚，但这一次，步骤3被phpize代替了。&lt;/p&gt;&#10;&lt;p&gt;按部就班，编辑config.m4，PHP_ARG_WITH是采用动态库方式加载（PHP_ARG_ENABLE则是编译内核中，configure是–enable-extension使用），将&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;dnl PHP_ARG_WITH(courages, whether to enable courages support,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;dnl Make sure that the comment is aligned:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;dnl [ --with-courages Include courages support])&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;更改为&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;PHP_ARG_WITH(courages, for courages support,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[ --with-courages Include courages support])&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;然后，在php_courages.h增加函数声明&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;PHP_FUNCTION(confirm_courages_compiled);&#9;&lt;span style="color:#75715e"&gt;/* For testing, remove later. */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;PHP_FUNCTION(courages_helloworld);&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;接着，编辑courages.c，在function_entry中增加函数注册&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; zend_function_entry courages_functions[] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;PHP_FE(confirm_courages_compiled,&#9;NULL)&#9;&#9;&lt;span style="color:#75715e"&gt;/* For testing, remove later. */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &#9;PHP_FE(courages_helloworld, NULL)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;PHP_FE_END&#9;&lt;span style="color:#75715e"&gt;/* Must be the last line in courages_functions[] */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;};&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;然后是courages_helloworld函数实现&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;PHP_FUNCTION(courages_helloworld)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;char&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;arg &lt;span style="color:#f92672"&gt;=&lt;/span&gt; NULL;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; arg_len, len;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&lt;span style="color:#66d9ef"&gt;char&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;strg;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, &lt;span style="color:#e6db74"&gt;&amp;#34;s&amp;#34;&lt;/span&gt;, &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;arg, &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;arg_len) &lt;span style="color:#f92672"&gt;==&lt;/span&gt; FAILURE) {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&#9;&lt;span style="color:#66d9ef"&gt;return&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;len &lt;span style="color:#f92672"&gt;=&lt;/span&gt; spprintf(&lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;strg, &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;Your input string: %s/n&amp;#34;&lt;/span&gt;, arg);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;php_printf(strg);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; SUCCESS;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;最后就是编译&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;phpize&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;./configure&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo make&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo make install&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo vim /etc/php.ini&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在php.ini中增加扩展courages.so&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[courages]&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;extension = courages.so&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;测试一下&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;vagrant@vagrant-centos64 courages&lt;span style="color:#f92672"&gt;]&lt;/span&gt;$ php -m | grep &lt;span style="color:#e6db74"&gt;&amp;#39;courages&amp;#39;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;courages&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;vagrant@vagrant-centos64 courages&lt;span style="color:#f92672"&gt;]&lt;/span&gt;$ php courages.php&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Functions available in the test extension:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;confirm_courages_compiled&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;courages_helloworld&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Your input string: hellow world&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Congratulations! You have successfully modified ext/courages/config.m4. Module courages is now compiled into PHP.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;到这里一个扩展的开发流程就结束了。&lt;/p&gt;&#10;&lt;p&gt;这里分享一些小技巧。&lt;br&gt;&#10;首先是如何在PHP扩展中获取PHP全局数组$_SERVER($_POST/GET)变量中的值：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;char&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;get_server_var_by_name&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;char&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;str){&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&lt;span style="color:#75715e"&gt;// This code makes sure $_SERVER has been initialized&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#f92672"&gt;!&lt;/span&gt;zend_hash_exists(&lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;EG(symbol_table), &lt;span style="color:#e6db74"&gt;&amp;#34;_SERVER&amp;#34;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;8&lt;/span&gt;)) {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&#9;zend_auto_global&lt;span style="color:#f92672"&gt;*&lt;/span&gt; auto_global;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&#9;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (zend_hash_find(CG(auto_globals), &lt;span style="color:#e6db74"&gt;&amp;#34;_SERVER&amp;#34;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;8&lt;/span&gt;, (&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#f92672"&gt;**&lt;/span&gt;)&lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;auto_global) &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; FAILURE) {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&#9;&#9;auto_global&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;armed &lt;span style="color:#f92672"&gt;=&lt;/span&gt; auto_global&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;auto_global_callback(auto_global&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;name, auto_global&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;name_len TSRMLS_CC);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&#9;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&lt;span style="color:#75715e"&gt;// This fetches $_SERVER[&amp;#39;PHP_SELF&amp;#39;]&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;zval&lt;span style="color:#f92672"&gt;**&lt;/span&gt; arr;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&lt;span style="color:#66d9ef"&gt;char&lt;/span&gt;&lt;span style="color:#f92672"&gt;*&lt;/span&gt; script_name;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (zend_hash_find(&lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;EG(symbol_table), &lt;span style="color:#e6db74"&gt;&amp;#34;_SERVER&amp;#34;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;8&lt;/span&gt;, (&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt;&lt;span style="color:#f92672"&gt;**&lt;/span&gt;)&lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;arr) &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; FAILURE) {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&#9;HashTable&lt;span style="color:#f92672"&gt;*&lt;/span&gt; ht &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Z_ARRVAL_P(&lt;span style="color:#f92672"&gt;*&lt;/span&gt;arr);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&#9;zval&lt;span style="color:#f92672"&gt;**&lt;/span&gt; val;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&#9;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (zend_hash_find(ht, str, strlen(str)&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, (&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt;&lt;span style="color:#f92672"&gt;**&lt;/span&gt;)&lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;val) &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; FAILURE) {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&#9;&#9;script_name &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Z_STRVAL_PP(val);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&#9;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; script_name;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;然后是如何在PHP扩展调用PHP函数:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;/*调用无参数函数*/&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;char&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;get_sapi_name&lt;/span&gt;(){&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; zval &lt;span style="color:#f92672"&gt;*&lt;/span&gt;function_name;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; zval &lt;span style="color:#f92672"&gt;*&lt;/span&gt;retval;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&lt;span style="color:#66d9ef"&gt;char&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;sapi_name;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; MAKE_STD_ZVAL(function_name);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ZVAL_STRING(function_name , &lt;span style="color:#e6db74"&gt;&amp;#34;php_sapi_name&amp;#34;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (call_user_function_ex(EG(function_table), NULL, function_name, &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;retval, &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, NULL, &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, EG(active_symbol_table) TSRMLS_CC) &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; SUCCESS)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; zend_error(E_ERROR, &lt;span style="color:#e6db74"&gt;&amp;#34;Function call failed&amp;#34;&lt;/span&gt;);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (retval &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; NULL &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; Z_TYPE_P(retval) &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; IS_STRING) {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; convert_to_string(retval);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; sapi_name &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Z_STRVAL_P(retval);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt;{&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;sapi_name &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;cli&amp;#34;&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; sapi_name;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;/*调用有参数函数*/&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;_ck_dir&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;char&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;dir TSRMLS_DC)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; zval &lt;span style="color:#f92672"&gt;*&lt;/span&gt;function_name;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; zval &lt;span style="color:#f92672"&gt;*&lt;/span&gt;retval;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; zval &lt;span style="color:#f92672"&gt;*&lt;/span&gt;str;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; zval &lt;span style="color:#f92672"&gt;**&lt;/span&gt;param[&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;];&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; MAKE_STD_ZVAL(function_name);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ZVAL_STRING(function_name , &lt;span style="color:#e6db74"&gt;&amp;#34;is_dir&amp;#34;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; MAKE_STD_ZVAL(str);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ZVAL_STRING(str, dir, &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; param[&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;str;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (call_user_function_ex(EG(function_table), NULL, function_name, &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;retval, &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, param, &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, EG(active_symbol_table) TSRMLS_CC) &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; SUCCESS)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; zend_error(E_ERROR, &lt;span style="color:#e6db74"&gt;&amp;#34;Function call failed&amp;#34;&lt;/span&gt;);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (retval &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; NULL &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; zval_is_true(retval)) {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; SUCCESS;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; FAILURE;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;更高级的一些技巧可以参考&lt;a class="link" href="https://github.com/walu/phpbook" target="_blank" rel="noopener"&#10; &gt;《PHP扩展开发及内核应用》&lt;/a&gt;和阅读别人的扩展开发代码。&lt;/p&gt;&#10;&lt;p&gt;参考链接：&lt;br&gt;&#10;&lt;a class="link" href="http://my.huhoo.net/archives/2008/02/php_ip.html" target="_blank" rel="noopener"&#10; &gt;php扩展实战 —— 获得ip的来源地址&lt;/a&gt;&lt;br&gt;&#10;&lt;a class="link" href="http://rango.swoole.com/archives/152" target="_blank" rel="noopener"&#10; &gt;如何编写一个PHP的C扩展&lt;/a&gt;&lt;br&gt;&#10;&lt;a class="link" href="http://blog.csdn.net/heiyeshuwu/article/details/3453854" target="_blank" rel="noopener"&#10; &gt;[原创]快速开发一个PHP扩展&lt;/a&gt;&lt;br&gt;&#10;&lt;a class="link" href="http://www.laruence.com/2009/04/28/719.html" target="_blank" rel="noopener"&#10; &gt;用C/C++扩展你的PHP&lt;/a&gt;&lt;br&gt;&#10;&lt;a class="link" href="http://stackoverflow.com/questions/12007841/get-the-name-of-running-script-from-a-php-extension" target="_blank" rel="noopener"&#10; &gt;Get the name of running script from a PHP extension&lt;/a&gt;&lt;br&gt;&#10;&lt;a class="link" href="http://stackoverflow.com/questions/13660407/build-php-extension-and-use-call-user-function" target="_blank" rel="noopener"&#10; &gt;Build PHP extension and use call_user_function&lt;/a&gt;&lt;br&gt;&#10;&lt;a class="link" href="http://docstore.mik.ua/orelly/webprog/php/ch14_10.htm" target="_blank" rel="noopener"&#10; &gt;Programming PHP&lt;/a&gt;&lt;br&gt;&#10;&lt;a class="link" href="http://php.net/manual/zh/internals2.buildsys.configunix.php" target="_blank" rel="noopener"&#10; &gt;与 UNIX 构建系统交互: config.m4&lt;/a&gt;&lt;br&gt;&#10;&lt;a class="link" href="http://forums.phpfreaks.com/topic/1303-call-user-function-ex-documentation/" target="_blank" rel="noopener"&#10; &gt;call_user_function_ex() documentation&lt;/a&gt;&lt;br&gt;&#10;&lt;a class="link" href="http://www.kchodorow.com/blog/2011/08/11/php-extensions-made-eldrich-php-variables/" target="_blank" rel="noopener"&#10; &gt;PHP Extensions Made Eldrich: PHP Variables&lt;/a&gt;&lt;br&gt;&#10;&lt;a class="link" href="http://stackoverflow.com/questions/3606125/convert-zval-to-char" target="_blank" rel="noopener"&#10; &gt;Convert Zval to char*&lt;/a&gt;&lt;br&gt;&#10;&lt;a class="link" href="http://weizhifeng.net/write-php-extension-part1.html" target="_blank" rel="noopener"&#10; &gt;PHP扩展编写第一步：PHP和Zend介绍&lt;/a&gt;&lt;br&gt;&#10;&lt;a class="link" href="http://www.phppan.com/2010/11/php-extension-1-simple-class/" target="_blank" rel="noopener"&#10; &gt;PHP扩展开发：简单类实现&lt;/a&gt;&lt;br&gt;&#10;&lt;a class="link" href="http://www.imsiren.com/archives/572" target="_blank" rel="noopener"&#10; &gt;自己写PHP扩展之创建一个类[原创]&lt;/a&gt;&lt;br&gt;&#10;&lt;a class="link" href="http://www.imsiren.com/archives/606" target="_blank" rel="noopener"&#10; &gt;如何在扩展里调用PHP函数呢?&lt;/a&gt;&lt;/p&gt;&#10;</description></item></channel></rss>