用C编写你自己的php扩展

本文链接:http://blog.csdn.net/ddjohn/article/details/42317675

本文参考:http://blog.csdn.net/taft/article/details/596291

如果你没写过php扩展,又是追求性能的极客,那么这篇文章肯定适合你:

假如你有这样一个php程序

function self_concat($string, $n){
    $result = "";
    for($i = 0; $i < $n; $i++){
        $result .= $string;
    }
    return $result;
}
$str = self_concat('fire',10);

如果传入的第二个参数N很大,程序的性能如何?我在自己的机器上测试下如果 n=10000000的时候耗时0.6s左右 如果用C写这个php function然后php直接调用,会快么?那就开始写这样一个简单的扩展吧,采用静态编译成.so的方式来加载,我用最快最简明的方式说明。

1.首先你需要有php的源码目录 cd到其ext目录下执行:

./ext_skel --extname=luckyext --proto=luckyext.def

这条命令会自动生成一个名叫luckyext的目录 里面有基本的扩展骨架文件,核心的文件只有三个 congif.m4用来做编译配置,luckyext.h定义都文件包括声明你的自定义函数,还有luckyext.c用来写C的函数源码,其他都是附加的骨架文件,暂时可以不用管。

2.在luckyext.c内编写你要的函数,记得在头文件内声明,不然编译的时候会报错

PHP_FUNCTION(self_concat_c)

{

char *str = NULL;

int argc = ZEND_NUM_ARGS();

int str_len;

long n;

char *result; /* Points to resulting string */

char *ptr; /* Points at the next location we want to copy to */

int result_length; /* Length of resulting string */

if (zend_parse_parameters(argc TSRMLS_CC, "sl", &str, &str_len, &n) == FAILURE)

return;

/* Calculate length of result */

result_length = (str_len * n);

/* Allocate memory for result */

result = (char *) emalloc(result_length + 1);

/* Point at the beginning of the result */

ptr = result;

while (n--) {

/* Copy str to the result */

memcpy(ptr, str, str_len);

/* Increment ptr to point at the next position we want to write to */

ptr += str_len;

}

/* Null terminate the result. Always null-terminate your strings

even if they are binary strings */

*ptr = '\0';

/* Return result to the scripting engine without duplicating it*/

RETURN_STRINGL(result, result_length, 0);

} 

3.编译扩展 关于php的环境配置就不说了

phpize
./configure
make&&make install

成功编译的话会在你的php指定的扩展目录中生成一个luckyext.so的文件

4.引入扩展重新加载php

vi /etc/php.ini
extension=luckyext.so

我是mac机,修改的时候请看自己机器的配置,修改完后保存重启fpm

killall php-fpm
php-fpm

5.测试

终端输入

php -m

出来的扩展中应该有luckyext了,至于它支持什么函数 可以用ext/luckyext目录内的luckyext.php脚本去运行看看 正常情况会输出它支持的函数self_concat_c()

6.性能对比 直接运行C写的php

<?php
self_concat_c('fire',10000000);

出来的结果耗时是惊人的,0.06秒,相差10倍!为什么呢,因为如果用php那套代码,每次往字符串塞字符的时候,php都需要做一个内存的动态分配,循环越多次,性能开销就越大,而C写的function直接就计算出最终需要分配多少内存了,所以快就快在这里,是不是很有趣~哈哈,至少我觉得很刺激!

本文的C例子属参考前辈翻译的文件,以后要多修修C的功底才行了,后面我会研究更多C的知识,加油!

时间: 2025-01-24 19:13:29

用C编写你自己的php扩展的相关文章

如何编写一个独立的PHP扩展

独立的 PHP 扩展可以独立于 PHP 源码之外进行分发.要创建一个这样的扩展,需要准备好两样东西: 配置文件 (config.m4) 你的模块源码 接下来我们来描述一下如果创建这些文件并组合起来. 准备好系统工具 想要扩展能够在系统上编译并成功运行,需要准备转以下工具: GNU autoconf GNU automake GNU libtool GNU m4 以上这些都可以从 ftp://ftp.gnu.org/pub/gnu/ 获取. 注:以上这些都是类 Unix 环境下才能使用的工具. 改

利用curl进行逆地理编码_c语言编写动态链接库对PostgreSQL进行扩展

流程: [1]c语言编写逆地理编码的函数,利用curl库和高德服务器进行地理坐标解析 [2]gcc生成动态链接库 [3]postgreSQL中加载动态链接库中的函数 [4]postgreSQL中将逆地理编码函数的返回类型进行转化 =========================================== [1]c语言编写逆地理编码的函数,利用curl库和高德服务器进行地理坐标解析 #include <stdio.h> #include <stdlib.h> #inclu

如何编写一个PHP的C扩展

为什么要用C扩展 C是静态编译的,执行效率比PHP代码高很多.同样的运算代码,使用C来开发,性能会比PHP要提升数百倍.IO操作如CURL,因为耗时主要在IOWait上,C扩展没有明显优势. 另外C扩展是在进程启动时加载的,PHP代码只能操作Request生命周期的数据,C扩展可操作的范围更广. 第一步 下载PHP的源代码,如php-5.4.16.解压后进入php-5.4.16\ext目录.输入 ./ext_skel –extname=myext,myext就是扩展的名称,执行后生成myext目

关于php编写64位扩展的问题

1.原本是在32位的桌面系统上编写了一个php的扩展,已经在本地调试好,可以正常使用了. 2.发布到服务器以后,扩展始终没有加载起来,通过phpinfo查看没有加载,服务器是ubuntu 14.04 64位版本 3.将php.ini中的中的错误显示项打开 display_startup_errors = On error_log = /etc/php_errors.log 以上设置可以显示php启动时的错误信息,例如扩展模块没有加载成功之类的. 4.停止再启动php5-fpm 命令:stop p

使用 Kotlin 编写你的第一个 Firefox WebExtension 扩展

Kotlin 是我最喜爱的编程语言.我们已经知道 Kotlin 编译成 Java 字节码可以快速被安卓和服务端采用.事实上,Kotlin 还支持编译成 JavaScript,因此该语言也开始在 Web 生态系统中受到关注. 尽管已经发布了许多 Kotlin 编写的 Web 应用程序,但至今人们都忽略了 Kotlin 还可以写浏览器扩展插件.所以我写了这篇文章,和大家一起探讨使用 Kotlin JS 编写一个简单的 Firefox 扩展插件的过程. 这个扩展程序基于 Mozilla 的 "你的第一

超强php加解密扩展:cryptopp

cryptopp是一个用c++编写的超强加解密扩展.性能优异可靠.完全可以替换所有PHP编写的加解密类.不仅如此,它的提供的编程接口非常简明易用,可说是PHP程序员必备扩展. cryptopp扩展的接口如下: class cryptopp { public function __construct($param); public function setkey($param); public function encode($param); public function decode($par

ThinkPHP应用模式扩展之谜

ThinkPHP应用模式提供了对核心框架进行改造的机会,可以让你的应用适应更多的环境和不同的需求.每个应用模式都有自己的模式定义文件,相对与ThinkPHP3.1版本,ThinkPHP3.2版本对应用模式的扩展更加明确和清晰,在ThinkPHP3.1版本中定义了Cli.Lite.Thin.AMF.PHPRPC.REST模式,其定义方式和ThinkPHP3.2版本的方式大同小异,如有需要可以参考修改,其中Cli模式被ThinkPHP框架内置,不用单独定义Cli模式即可正常使用,如需要更细化调整可以

Python和C扩展实现方法

一.Python和C扩展 cPython是C编写的,python的扩展可以用C来写,也便于移植到C++. 编写的Python扩展,需要编译成一个.so的共享库. Python程序中. 官方文档:https://docs.python.org/2/extending/extending.html#writing-extensions-in-c 二.举例 >>> import spam >>> status = spam.system("ls -l")

php的源代码包构建一个空的php扩展。

下载一个php的源代码包,这里使用的是php 4.0.5版,解压后会看到php的根目录下会有README.EXT_SKEL这样一个文件,打开详细阅读了一下,发现了一个非常好用的工具,这个工具可以帮你构建一个空的php扩展,然后你向里面添加相应的代码就可以完成你自己的功能扩展了. 首先转移你的目录到php的目录下的ext目录,如果你只需要一个基本的扩展框架的话,执行下面的命令: ./ext_skel --extname=module_name module_name是你自己可以选择的扩展模块的名字