首页 > 编程语言 >PHP内核的学习--创建PHP扩展

PHP内核的学习--创建PHP扩展

时间:2023-10-08 09:46:13浏览次数:40  
标签:-- util skel ext 内核 str PHP result

开始看PHP内核也有一段时间了,现在开始边学边总结,今天就总结一下如何创建自己的PHP扩展。

我的环境如下:

系统:Ubuntu 14.04

php版本:5.5.19

参考摘录:用C/C++扩展你的PHP

PHP取得成功的一个主要原因之一是它拥有大量的可用扩展。web开发者无论有何种需求,这种需求最有可能在PHP发行包里找到。PHP发行包包括支持各种数据库,图形文件格式,压缩,XML技术扩展在内的许多扩展。

扩展API的引入使PHP3取得了巨大的进展,扩展API机制使PHP开发社区很容易的开发出几十种扩展。现在,两个版本过去了,API仍然和PHP3时的非常相似。扩展主要的思想是:尽可能的从扩展编写者那里隐藏PHP的内部机制和脚本引擎本身,仅仅需要开发者熟悉API。

有两个理由需要自己编写PHP扩展。第一个理由是:PHP需要支持一项她还未支持的技术。这通常包括包裹一些现成的C函数库,以便提供PHP接口。例如,如果一个叫FooBase的数据库已推出市场,你需要建立一个PHP扩展帮助你从PHP里调用FooBase的C函数库。这个工作可能仅由一个人完成,然后被整个PHP社区共享(如果你愿意的话)。第二个不是很普遍的理由是:你需要从性能或功能的原因考虑来编写一些商业逻辑。

假设你正在开发一个网站,需要一个把字符串重复n次的函数。下面是用PHP写的例子:

复制代码
function util_str_repeat($string, $n){
    $result = "";
    for($i = 0; $i < $n; $i++){
        $result .= $string;
    }
    return $result;
}
 
util_str_repeat("One", 3);// returns "OneOneOne".
util_str_repeat("One", 1);// returns "One".
复制代码

假设由于一些奇怪的原因,你需要时常调用这个函数,而且还要传给函数很长的字符串和大值n。这意味着在脚本里有相当巨大的字符串连接量和内存重新分配过程,以至显著地降低脚本执行速度。如果有一个函数能够更快地分配大量且足够的内存来存放结果字符串,然后把$string重复n次,就不需要在每次循环迭代中分配内存。

为扩展建立函数的第一步是写一个函数定义文件,该函数定义文件定义了扩展对外提供的函数原形。该例中,定义函数只有一行函数原形util_str_repeat() :

string util_str_repeat(string str, int n)

函数定义文件的一般格式是一个函数一行。你可以定义可选参数和使用大量的PHP类型,包括: bool, float, int, array等。

保存为util.def文件至PHP原代码目录树下(即与ext_skel文件放在同一目录下,我的目录是/usr/share/php5/)。

然后就是通过扩展骨架(skeleton)构造器运行函数定义文件的时机了。该构造器脚本就是ext_skel。假设你把函数定义保存在一个叫做util.def的文件里,而且你希望把扩展取名为util,运行下面的命令来建立扩展骨架:

sudo ./ext_skel --extname=util --proto=util.def

执行之后,我这里报了如下错误:

复制代码
./ext_skel: 1: cd: can't cd to /usr/lib/php5/skeleton
Creating directory util
awk: cannot open /create_stubs (No such file or directory)
Creating basic files: config.m4 config.w32 .svnignore util.c./ext_skel: 216: ./ext_skel: cannot open /skeleton.c: No such file
 php_util.h./ext_skel: 234: ./ext_skel: cannot open /php_skeleton.h: No such file
 CREDITS./ext_skel: 238: ./ext_skel: cannot open /CREDITS: No such file
 EXPERIMENTAL./ext_skel: 242: ./ext_skel: cannot open /EXPERIMENTAL: No such file
 tests/001.phpt./ext_skel: 247: ./ext_skel: cannot open /tests/001.phpt: No such file
 util.php./ext_skel: 251: ./ext_skel: cannot open /skeleton.php: No such file
rm: cannot remove ‘function_entries’: No such file or directory
rm: cannot remove ‘function_declarations’: No such file or directory
rm: cannot remove ‘function_stubs’: No such file or directory
 [done].

To use your new extension, you will have to execute the following steps:

1.  $ cd ..
2.  $ vi ext/util/config.m4
3.  $ ./buildconf
4.  $ ./configure --[with|enable]-util
5.  $ make
6.  $ ./php -f ext/util/util.php
7.  $ vi ext/util/util.c
8.  $ make

Repeat steps 3-6 until you are satisfied with ext/util/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.
复制代码

很明显是/usr/lib/php5/skeleton路径的错误,编辑ext_skel文件,将/usr/lib/php5/skeleton修改为/usr/share/php5/skeleton,然后移除掉生成的util文件夹,再次执行之前的命令,成功后提示如下:

复制代码
Creating directory util
Creating basic files: config.m4 config.w32 .svnignore util.c php_util.h CREDITS EXPERIMENTAL tests/001.phpt util.php [done].

To use your new extension, you will have to execute the following steps:

1.  $ cd ..
2.  $ vi ext/util/config.m4
3.  $ ./buildconf
4.  $ ./configure --[with|enable]-util
5.  $ make
6.  $ ./php -f ext/util/util.php
7.  $ vi ext/util/util.c
8.  $ make

Repeat steps 3-6 until you are satisfied with ext/util/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.
复制代码

然后采用静态编译的方式编译扩展。为了使扩展能够被编译,需要修改扩展目录util/下的config.m4文件。扩展没有包裹任何外部的C库,你需要添加支持–enable-util配置开关到PHP编译系统里(–with-extension 开关用于那些需要用户指定相关C库路径的扩展)。找到如下内容:

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

将前面的dnl 去掉,修改为如下结果:

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

然后修改util.c文件,找到如下代码:

复制代码
PHP_FUNCTION(util_str_repeat)
{
    char *str = NULL;
    int argc = ZEND_NUM_ARGS();
    int str_len;
    long n;

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

    php_error(E_WARNING, "util_str_repeat: not yet implemented");
}
复制代码

将其修改为如下代码:

复制代码
PHP_FUNCTION(util_str_repeat)
{
    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); }
复制代码

里面的具体内容,就不在这里说了,之后会慢慢写到。

攻略大全-第5页-攻略-9335游戏网

然后就是编译,安装。在util目录下,命令如下(命令可能都需要加sudo):

phpize
./configure
make
make test
make install

然后配置生成的扩展文件,在php5.5版本中,进入到/etc/php5/mods-available目录下,创建util.ini文件,写入如下内容:

extension=util.so

然后enable util扩展

sudo php5enmod util

最后,重启php-fpm

sudo service php5-fpm restart

创建一个php文件,测试一下,测试文件如下:

<?php
for ($i = 1; $i <= 3; $i++) {
    print util_str_repeat("CraryPrimitiveMan ", $i);
    print "\n";
}
?>

执行结果如下:

CraryPrimitiveMan 
CraryPrimitiveMan CraryPrimitiveMan 
CraryPrimitiveMan CraryPrimitiveMan CraryPrimitiveMan

这样我们就成功创建了一个包含简单的PHP函数的扩展。

https://www.clw9335.com/gl/485699.html

 

标签:--,util,skel,ext,内核,str,PHP,result
From: https://www.cnblogs.com/zx8868/p/17748108.html

相关文章

  • [Microsoft Azure] 创建你的第一个Azure Functions 应用
    随着云计算和Serverless架构的普及,微服务变得越来越受欢迎。AzureFunctions是MicrosoftAzure提供的一种Serverless服务,可以让你在Azure上快速部署和运行代码,而无需管理底层服务器。在这篇文章中,我们将带你创建一个简单的AzureFunctions应用,并了解其基本概念和工作原理。一......
  • 国庆丨龙腾东方,恭贺华诞
    山河披锦绣,盛世写华章。今天是国庆节,计讯物联在这里祝祖国:国泰民安!祝大家:国庆快乐!   ......
  • 服务器动态下线
     ######haproxy动态下线需要用到socat工具socat工具:对服务器动态权重和其它状态可以利用socat工具进行调整,Socat是Linux下的一个多功能的网络工具,名字来由是SocketCAT,相当于netCAT的增强版.Socat的主要特点就是在两个数据流之间建立双向通道,且支持众多协......
  • PHP生成word的三种方式
    最近工作遇到关于生成word的问题现在总结一下生成word的三种方法。btw:好像在博客园发表博客只要是标题带PHP的貌似点击量都不是很高(哥哥我标题还是带上PHP了),不知道为什么,估计博客园上net技术大牛比较多吧,如果把java,.net,php比作程序员的女友,那么java是Oracle门下的大家闺秀,.net微......
  • 我准备告别音乐付费会员了
    起因源于跑步听音乐这件事,习惯把淘汰掉的手机拿来当音乐播放器用。旧手机没网络卡只能先将音乐下载后放到旧手机中。那么问题来了,一直用的网易云音乐,最多免费下载3首的样子,如果需要批量下载就需要掏钱。话说,掏钱也没啥,主要是涉及到音乐版权问题,有些歌曲到其他平台才能下到正版......
  • 编写脚本实现tomcat一键安装8.5版本
    #下载包到/root目录[root@tomcat~]#lljdk-8u212-linux-x64.tar.gzapache-tomcat-8.5.82.tar.gz-rw-r--r--1rootroot10610025Aug2717:14apache-tomcat-8.5.82.tar.gz-rw-r--r--1rootroot195013152Aug2717:08jdk-8u212-linux-x64.tar.gz#编写脚本[root@to......
  • wsl中matplotlib安装中文字体
    wsl中matplotlib安装中文字体首先修改matplotlib配置的中文字体使用python定位字体路径importmatplotlibmatplotlib.matplotlib_fname()打开电脑的C:windows/fonts下,查找yahei关键字,将微软雅黑ttf字体拷贝,扔到wsl中显示的路径下的fonts/ttf文件夹里面。删除matplot......
  • slices in Go 1.21
    Go1.21中新增的slices包中提供了很多与切片相关的函数,适用于任意类型的切片。本文内容来自官方文档BinarySearch函数签名如下:funcBinarySearch[S~[]E,Ecmp.Ordered](xS,targetE)(int,bool)BinarySearch在已排序的切片中搜索target并返回找到target的位置,或......
  • 媒体查询+scss 响应式开发
    ```bash$color:#3497ee;@mixinopacity($value){opacity:$value;filter:alpha(opacity=$value*100);}@mixintransition($obj,$time){-webkit-transition:$obj$time;-moz-transition:$obj$time;-ms-transition:$obj$time;trans......
  • destoon : 后台无法登录问题解决
    经常有朋友在destoon搬家的时候,数据还原之后,会出现后台无法登录的情况.具体表现为后台帐号密码输入后点击确定,页面刷新.并没有跳转到相应后台页面.但是如果帐号密码输入错误,会提示密码错误的情况.这种情况多半是原系统设置中,设置了cookie作用域的问题,如......