开发一个简易的PHP扩展

本教程将实现一个阶乘扩展,编译环境为:CentOS7/PHP5.6.3,其PHP函数实现如下:

function factorial($number){
  if($number < 1) return 0;
  $i = 1;
  $result = 1;
  while($i <= $number){
    $result *= $i;
    $i++;
  }
  return $result;
}

注意:由于这个函数只用于演示,未考虑大数的阶乘,在使用大数进行阶乘时,有可能会发生整形溢出。

定义函数原型

我们首先在php源码的扩展目录定义一个文件名为"factorial.def"的文件,并在里面写上如下内容:

long factorial(int number)

生成扩展基本代码

这时候我们就可以使用php官方为我们提供的工具ext_skel,来生成扩展的基本代码,命令如下:

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

其中extname表示要生成的扩展名称,proto表示函数原型的文件路径

扩展配置修改

经过上一步的代码生成,现在当前目录下应该出现了一个factorial的目录,我们进入这个目录,并编辑目录下的“config.m4”文件,将以下两行代码前的dnl删除,如下:

PHP_ARG_ENABLE(factorial, whether to enable factorial support,
Make sure that the comment is aligned:
[  --enable-factorial           Enable factorial support])

功能实现

接下来就是我们今天的主菜了,我们修改一下factorial.c,找到函数主体,修改为如下代码:

PHP_FUNCTION(factorial)
{
  int argc = ZEND_NUM_ARGS();
  long number;

  if (zend_parse_parameters(argc TSRMLS_CC, "l", &number) == FAILURE)
  	return;

  if(number < 1)  RETURN_LONG(0);
  long i = 1;
  long result = 1;
  while(i <= number){
    result *= i;
  	i++;
  }

  RETURN_LONG(result);
}

代码中的zend_parse_parameters是用来检验输入参数的,它的第三个参数表示的是输入参数的类型,觉的类型表示如下表所示:

类型指定符对应的C类型描述
llong长整数
ddouble浮点数
schar *, int二进制字符串,长度
bzend_bool逻辑型(1或0)
rzval *资源(文件指针,数据库连接等)
azval *联合数组
ozval *任何类型的对象
Ozval *指定类型的对象。需要提供目标对象的类类型
zzval *无任何操作的zval
foofoofoo
barbarbar
bazbazbaz

扩展函数的返回值,需要使用php预设的宏定义来返回,常见的宏定义如下表所示:

宏定义设置返回值宏返回类型和参数
RETURN_LONG(l)RETVAL_LONG(l)整数
RETURN_BOOL(b)RETVAL_BOOL(b)布尔数(1或0)
RETURN_NULL()RETVAL_NULL()NULL
RETURN_DOUBLE(d)RETVAL_DOUBLE(d)浮点数
RETURN_STRING(s, dup)RETVAL_STRING(s, dup)字符串。如果dup为1,引擎会调用estrdup()重复s,使用拷贝。如果dup为0,就使用s
RETURN_STRINGL(s, l, dup)RETVAL_STRINGL(s, l, dup)长度为l的字符串值。与上一个宏一样,但因为s的长度被指定,所以速度更快。
RETURN_TRUERETVAL_TRUE返回布尔值true。注意到这个宏没有括号。
RETURN_FALSERETVAL_FALSE返回布尔值false。注意到这个宏没有括号。
RETURN_RESOURCE(r)RETVAL_RESOURCE(r)资源句柄。

编译扩展

执行以下命令,执行扩展编译:

/usr/local/php/bin/phpzie
./configure
make && make install

添加扩展

编辑php.ini,加入如下代码:

extension=factorial.so

代码添加后,我们需要重启一下php-fpm. 至此,我们就将扩展添加进PHP了,这时我们可以编写一个php文件来做测试,如下:

echo factorial(10);
// returns 3628800

转载于:https://my.oschina.net/jathon/blog/880359

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值