ホームページ >バックエンド開発 >PHPチュートリアル >php-extension - php扩展开发的问题。
现在网上有很多PHP开发的的教程和关于PHP底层的WIKI,我想如果想开发PHP7的扩展看这些有用吗?还是这些只能开发PHP5几的扩展?
现在网上有很多PHP开发的的教程和关于PHP底层的WIKI,我想如果想开发PHP7的扩展看这些有用吗?还是这些只能开发PHP5几的扩展?
思路差不多的.PHP7源代码ext下的扩展的代码可以说都是标准范例.
还有,鸟哥的Yaf/Yar/Yac等等,峰哥的Swoole都已经支持PHP7了,
这些第三方扩展可以在 pecl.php.net 上找到.
http://www.laruence.com/2011/09/13/2139.html
入门: http://www.walu.cc/phpbook/
案例: php-src/ext
PECL开发邮件组: http://news.php.net/php.pecl.dev
尽量编写一些phpt测试用例,php-src/tests下有很多参考.
测试时用--enable-debug编译PHP,要做到执行你的扩展逻辑,不输出任何错误信息.
用valgrind检测内存泄露.
Swoole作者峰哥教你怎么构建PHP扩展(视频教程):
http://wiki.swoole.com/wiki/page/238.html
http://php.net/manual/zh/internals2.buildsys.php
php-src/ext/ext_skel脚本用于生成PECL扩展源码骨架.
PECL扩展开发步骤(假设你的扩展名叫codenc):
cd php-src/ext
./ext_skel --extname=codenc
Creating directory codenc
Creating basic files:
config.m4 扩展的configure配置文件(Linux)
config.w32 扩展的configure配置文件(Windows)
codenc.c 扩展主文件
php_codenc.h 扩展头文件(定义扩展版本号PHP_CODENC_VERSION)
codenc.php 显示扩展提供的函数
tests/001.phpt 测试脚本
CREDITS 鸣谢
EXPERIMENTAL 实验
.svnignore SVN忽略目录或文件.deps,.lo,.la
<code>[done]. To use your new extension, you will have to execute the following steps: 1. $ cd .. 2. $ vi ext/codenc/config.m4 3. $ ./buildconf 4. $ ./configure --[with|enable]-codenc 5. $ make 6. $ ./sapi/cli/php -f ext/codenc/codenc.php 7. $ vi ext/codenc/codenc.c 8. $ make Repeat steps 3-6 until you are satisfied with ext/codenc/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. </code>
编辑config.m4:
把:
<code>dnl PHP_ARG_ENABLE(codenc, whether to enable codenc support, dnl Make sure that the comment is aligned: dnl [ --enable-codenc Enable codenc support]) </code>
改成:
<code>PHP_ARG_ENABLE(codenc, whether to enable codenc support, [ --enable-codenc Enable codenc support]) </code>
其中dnl是注释符号.
编辑config.w32:
把:
<code>// ARG_ENABLE("codenc", "enable codenc support", "no"); </code>
改为:
<code>ARG_ENABLE("codenc", "enable codenc support", "no"); </code>
执行phpize根据config.m4生成扩展的configure脚本:
<code>/png/php/5.4.39NTS/bin/phpize Configuring for: PHP Api Version: 20100412 Zend Module Api No: 20100525 Zend Extension Api No: 220100525 </code>
执行configure生成Makefile用于make编译:
<code>./configure --with-php-config=/png/php/5.4.39NTS/bin/php-config checking ... config.status: creating config.h </code>
执行 make && make install 编译并安装扩展:
<code>Libraries have been installed in: /home/eechen/png_stack/php-5.4.39/ext/codenc/modules Installing shared extensions: /png/php/5.4.39NTS/lib/php/extensions/no-debug-non-zts-20100525/ </code>
在 php.ini 加载扩展:
<code>extension=codenc.so </code>
测试:
<code>php -r 'echo confirm_codenc_compiled("codenc")."\n";' </code>
输出:
Congratulations! You have successfully modified ext/codenc/config.m4.
Module codenc is now compiled into PHP.
打开 php_codenc.h 和 codenc.c 可见其自动生成了一个用于测试的函数 confirm_codenc_compiled
<code>php_codenc.h(声明): PHP_FUNCTION(confirm_codenc_compiled); /* For testing, remove later. */ codenc.c(注册跟实现): const zend_function_entry codenc_functions[] = { PHP_FE(confirm_codenc_compiled, NULL) /* For testing, remove later. */ PHP_FE_END /* Must be the last line in codenc_functions[] */ }; PHP_FUNCTION(confirm_codenc_compiled) {} </code>
修改代码后,重新执行 make && make install 编译安装.
PECL模块加载卸载时执行的函数:
MINIT: Module Init (Beast和Blenc模块解密时会在这里重写zend_compile_file.缓存模块APC和Opcache也是在此起作用)
RINIT: Request Init (Session模块和VLD扩展都在这里起作用,VLD能够兼容Beast和Opcache)
RSHUTDOWN: Request Shutdown (register_shutdown_function,FPM提供的fastcgi_finish_request在这里起作用)
MSHUTDOWN: Module Shutdown (Beast和Blenc模块在这里重置函数 zend_compile_file = old_compile_file)
PHP_MINIT_FUNCTION(MyModule);
当模块被Zend Engine加载后,例如Apache或者PHP-FPM启动,加载了PHP模块,
Zend Engine会对每一个扩展模块调用此函数(如果有的话),可以在该函数里进行一些初始化操作.
PHP_MSHUTDOWN_FUNCTION(MyModule);
当Zend Engine收到shutdown信号后,例如Apache卸载PHP模块,
Zend Engine对每一个模块调用此函数,最后关闭自己的核心子系统.
PHP_RINIT_FUNCTION(MyModule);
对于每一个使用该模块的PHP脚本请求前,都执行该函数(如果有的话).
最好的例子:Session扩展模块,如果在一个PHP脚本里执行session.start(),
Session模块的PHP_RINIT_FUNCTION()将被调用.
PHP_RSHUTDOWN_FUNCTION(MyModule);
与PHP_RINIT_FUNCTION()相反,该函数是在一个PHP脚本执行完毕后执行,
比如PHP-FPM提供的函数fastcgi_finish_request.