Home > Backend Development > PHP Tutorial > php-extension - php扩展开发的问题。

php-extension - php扩展开发的问题。

WBOY
Release: 2016-06-06 20:22:09
Original
1310 people have browsed it

现在网上有很多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>
Copy after login

编辑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>
Copy after login

改成:

<code>PHP_ARG_ENABLE(codenc, whether to enable codenc support,
[  --enable-codenc           Enable codenc support])
</code>
Copy after login

其中dnl是注释符号.
编辑config.w32:
把:

<code>// ARG_ENABLE("codenc", "enable codenc support", "no");
</code>
Copy after login

改为:

<code>ARG_ENABLE("codenc", "enable codenc support", "no");
</code>
Copy after login

执行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>
Copy after login

执行configure生成Makefile用于make编译:

<code>./configure --with-php-config=/png/php/5.4.39NTS/bin/php-config
checking ...
config.status: creating config.h
</code>
Copy after login

执行 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>
Copy after login

在 php.ini 加载扩展:

<code>extension=codenc.so
</code>
Copy after login

测试:

<code>php -r 'echo confirm_codenc_compiled("codenc")."\n";'
</code>
Copy after login

输出:
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>
Copy after login

修改代码后,重新执行 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.

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template