代码,应该是下面两种情况: 在 php 程序中需要用到 C 代码,应该是下面两种情况: 1 已有 C 代码,在 php 程序中想直接用 代码, 2 由于 php 的性能问题,需要用 C 来实现部分功能 的性能问题,
针对第一种情况, 调用, 代码写成一个独立的程序。 针对第一种情况,最合适的方法是用 system 调用,把现有 C 代码写成一个独立的
程序。参数 通过命令行或者标准输入传入,结果从标准输出读出。其次, 通过命令行或者标准输入传入,结果从标准输出读出。其次,稍麻烦一点的方法是 C 代码写成 来和它进行通讯。 一个 daemon,php 程序用 socket 来和它进行通讯。 ,
重点讲讲第二种情况, 调用的方法也可以,但是想想你的目的是优化性能, 重点讲讲第二种情况,虽然沿用 system 调用的方法也可以,但是想想你的目的是优化性能, 那么频繁的起这么多进程,当然会让性能下降。 的方法固然可行, 那么频繁的起这么多进程,当然会让性能下降。而写 daemon 的方法固然可行,可是繁琐了 很多。 很多。
我的简单测试,同样一个算法, 我的简单测试,同样一个算法,用 C 来写比用 php 效率能提高 500 倍。而用 php 扩展的方 多倍(其中的性能损失在了参数传递上了吧,我猜)。 式,也能提高 90 多倍(其中的性能损失在了参数传递上了吧,我猜)。
扩展就是我们的最佳选择了。 所以有些时候 php 扩展就是我们的最佳选择了。
扩展的方法, 这里我着重介绍一下用 C 写 php 扩展的方法,而且不需要重新编译 php。 。
首先, 的源码, 版本的都可以, 首先,找到一个 php 的源码,php4 或者 php5 版本的都可以,与你目标平台的 php 版本没 有关系。 有关系。
在 源 码 的 ext 目 录 下 可 以 找 到 名 为 ext_skel 的 脚 本 ( windows 平 台 使 用 ext_skel_win32.php) ) 在这个目录下执行./ext_skel --extname=hello(我用 hello 作为例子) 作为例子) 在这个目录下执行 ( 这时生成了一个目录 hello,目录下有几个文件,你只需要关心这三个:config.m4 hello.c ,目录下有几个文件,你只需要关心这三个: php_hello.h
把这个目录拷备到任何你希望的地方, 进去, 把这个目录拷备到任何你希望的地方,cd 进去,依次执行 (安装 phpize 等工具 yum -y install php-devel ) phpize ./configure make 什么也没发生,对吧? 什么也没发生,对吧? 这是因为漏了一步, 这是因为漏了一步,打开 config.m4,找到下面 ,
1
dnl If your extension references something external, use with: ... dnl Otherwise use enable: ... 这是让你选择你的扩展使用 with 还是 enable,我们用 with 吧。把 with 那一部分取消注 , 释。 编辑器, 三个字母原来是
表示注释的呀( 如果你和我一样使用 vim 编辑器, 你就会很容易发现 dnl 三个字母原来是表示注释的呀 这是 ( 默认带了各种文件格式的语法着色包) 因为 vim 默认带了各种文件格式的语法着色包)
我们修改了 config.m4 后,继续 phpize ./configure make 这时, 文件。一个是动态库,一个是静态库。 这时,modules 下面会生成 hello.so 和 hello.la 文件。一个是动态库,一个是静态库。
扩展已经做好了,尽管它还没有实现你要的功能,我先说说怎么使用这个扩展吧! 你的 php 扩展已经做好了,尽管它还没有实现你要的功能,我先说说怎么使用这个扩展吧! ext_skel 为你生成了一个 hello.php 里面有调用示例,但是那个例子需要你把 hello.so 拷 里面有调用示例, 的扩展目录中去,我们只想实现自己的功能, 贝到 php 的扩展目录中去,我们只想实现自己的功能,不想打造山寨版 php,改用我下面的 , 方法来加载吧: 方法来加载吧: if(!extension_loaded("hello")) { dl_local("hello.so"); } function dl_local( $extensionFile ) { //make sure that we are ABLE to load libraries if( !(bool)ini_get( "enable_dl" ) || (bool)ini_get( "saf