文档章节

如何基于 PHP-X 快速开发一个 PHP 扩展

o
 osc_0ge9xs2w
发布于 2019/11/06 16:26
字数 1302
阅读 30
收藏 0

「深度学习福利」大神带你进阶工程师,立即查看>>>

0x01 起步

PHP-X本身基于C++11开发,使用cmake进行编译配置。首先,你需要确定所有依赖项已安装好。包括:

  • gcc-4.8 或更高版本
  • PHP7.0 或更高版本,需要php7-dev 开发包
  • cmake-2.8 或更高版本

然后安装PHP-X。

git clone https://github.com/swoole/PHP-X.git
cd PHP-X
cmake .
make -j 4
sudo make install

 

未出现任何编译错误,会成功编译出libphpx.so,并安装到系统的lib目录。头文件会复制到系统的include目录。这时需要执行 sudo ldconfig刷新so文件缓存。

0x02 新建工程

使用任意开发工具,新建一个http://test.cc源文件。首先需要引入phpx.h头文件。然后使用using引入phpx的命名空间。PHP官方未使用C++,因此phpx直接使用了php作为命名空间。

#include <phpx.h>
using namespace std;
using namespace php;

 

创建扩展使用PHPX_EXTENSION宏来实现。在这宏中只需要new Extension即可创建扩展。构造方法接受2个参数,第一个是扩展的名称,第二个是扩展的版本号。在PHPX_EXTENSION宏中return这个扩展对象的指针。

PHPX_EXTENSION()
{
    Extension *ext = new Extension("test", "0.0.1");
    return ext;
}

 

这里必须使用 new Extension,而不能直接在栈上创建对象

0x03 增加函数

一个PHP扩展的主要作用就是提供扩展函数,扩展函数由于是用C/C++代码实现,因此它的性能会比PHP用户函数性能高几十甚至上百倍。在phpx中实现函数非常简单。使用PHPX_FUNCTION来实现扩展函数,然后调用Extension::registerFunction来注册扩展函数。

PHPX_FN是一个助手宏,实际上展开就是"cpp_hello_world", cpp_hello_world PHPX_FUNCTION展开后,包含了2个变量,第一个是参数args,第二个是返回值retval
通过操作args和retval两个变量,就可以实现函数的输入和输出

这里我们的代码非常简单,cpp_test($str, $n),调用这个函数返回一个$n个$str的数组。

 1 #include <phpx.h>
 2 using namespace std;
 3 using namespace php;
 4 
 5 //声明函数
 6 PHPX_FUNCTION(cpp_test);
 7 
 8 PHPX_EXTENSION()
 9 {
10     Extension *ext = new Extension("test", "0.0.1");
11     ext->registerFunction(PHPX_FN(cpp_test));
12     return ext;
13 }
14 
15 //实现函数
16 PHPX_FUNCTION(cpp_test)
17 {
18     //args[1] 就是这个扩展函数的第 2 个参数
19     long n = args[1].toInt();
20     
21     //将返回值 retval 初始化为数组
22     Array _array(retval);
23     
24     for(int i = 0; i < n; i++)
25     {
26         //args[0] 就是这个扩展函数的第 1 个参数
27         //append 方法表示向数组中追加元素
28         _array.append(args[0]);
29     }
30 }

 

0x04 编译扩展

编写一个Makefile文件。内容如下:

 1 PHP_INCLUDE = `php-config --includes`
 2 PHP_LIBS = `php-config --libs`
 3 PHP_LDFLAGS = `php-config --ldflags`
 4 PHP_INCLUDE_DIR = `php-config --include-dir`
 5 PHP_EXTENSION_DIR = `php-config --extension-dir`
 6 
 7 test.so: test.cc
 8     c++ -DHAVE_CONFIG_H -g -o test.so -O0 -fPIC -shared test.cc -std=c++11 ${PHP_INCLUDE} -I${PHP_INCLUDE_DIR} -lphpx
 9     
10 install: test.so
11     cp test.so ${PHP_EXTENSION_DIR}/
12 clean:
13     rm *.so

 

php-config 这个工具是PHP提供的,使用php-config可以得到PHP的安装路径、头文件目录、扩展目录、其他额外的编译参数等等。

这个Makefile支持了3个指令,make编译,make clean清理,make install安装到扩展目录中。

这里可能需要root权限,使用sudo make install进行安装
直接从网页复制,可能会出现tab制表符被替换为空格,请手工编辑一下Makefile使用tab缩进 MacOS下需要在c++编译参数中增加-undefined dynamic_lookup

编写好之后执行make install,就会编译扩展并将扩展test.so安装到PHP的扩展目录中。这时需要修改php.ini加入extension=test.so加载扩展。

使用php -m来观察你的扩展是否正常加载。

 1 php -m
 2 [PHP Modules]
 3 Core
 4 ctype
 5 curl
 6 date
 7 dom
 8 fileinfo
 9 filter
10 gd
11 hash
12 iconv
13 inotify
14 json
15 libxml
16 mbstring
17 mcrypt
18 memcached
19 mongodb
20 mysqli
21 mysqlnd
22 openssl
23 pcntl
24 pcre
25 PDO
26 pdo_mysql
27 pdo_sqlite
28 Phar
29 posix
30 redis
31 Reflection
32 session
33 SimpleXML
34 sockets
35 SPL
36 sqlite3
37 standard
38 swoole
39 test
40 tokenizer
41 xml
42 xmlreader
43 xmlwriter
44 yac
45 zlib
46 zmq
47 
48 [Zend Modules]

 

这里看到test,表明你的扩展已经加载成功了,现在就可以调用cpp_test这个扩展函数了。

0x05 执行

编写一个test.php,内容为:

 1 <?php
 2 var_dump(cpp_test("hello", 3));
 3 执行test.php:
 4 
 5 php test.php
 6 array(3) {
 7   [0]=>
 8   string(5) "hello"
 9   [1]=>
10   string(5) "hello"
11   [2]=>
12   string(5) "hello"
13 }

 

可以看到执行结果符合预期。那么恭喜你,现在你已经成功地开发了一个PHP扩展了。是不是很简单?

0x06 更多

上面的例子还比较简单,只是编写了一个扩展函数。要真正在实际项目中使用PHP-X你还有很多工作要做。

  • 需要C++的功底
  • 了解更多PHP-X的 API

另外配合使用Eclipse等IDE工具,可以实现API自动提示和补齐,开发起来会更顺手。

相比Zend API,PHP-X要简单易用地多了,相信你不会花太多时间就可以掌握此项技能。在接下来我会撰写更多教程,教大家如何使用PHP-X实现扩展类、资源、回调函数等更复杂的功能。

o
粉丝 0
博文 500
码字总数 0
作品 0
私信 提问
加载中
请先登录后再评论。
Netty那点事(三)Channel与Pipeline

Channel是理解和使用Netty的核心。Channel的涉及内容较多,这里我使用由浅入深的介绍方法。在这篇文章中,我们主要介绍Channel部分中Pipeline实现机制。为了避免枯燥,借用一下《盗梦空间》的...

黄亿华
2013/11/24
2W
22
beego API开发以及自动化文档

beego API开发以及自动化文档 beego1.3版本已经在上个星期发布了,但是还是有很多人不了解如何来进行开发,也是在一步一步的测试中开发,期间QQ群里面很多人都问我如何开发,我的业余时间实在...

astaxie
2014/06/25
2.7W
22
程序猿媛一:Android滑动翻页+区域点击事件

滑动翻页+区域点击事件 ViewPager+GrideView 声明:博文为原创,文章内容为,效果展示,思路阐述,及代码片段。文尾附注源码获取途径。 转载请保留原文出处“http://my.oschina.net/gluoyer...

花佟林雨月
2013/11/09
4.3K
1
5分钟 maven3 快速入门指南

前提条件 你首先需要了解如何在电脑上安装软件。如果你不知道如何做到这一点,请询问你办公室,学校里的人,或花钱找人来解释这个给你。 不建议给Maven的服务邮箱来发邮件寻求支持。 安装Mav...

fanl1982
2014/01/23
1.2W
8
NSSplitView 扩展--DMSplitView

DMSplitView 对标准的 OS X 的 NSSplitView 控件进行改造,可满足更复杂的要求: 子视图的大小和约束 分隔条位置 可收缩伸展的子视图 动画变换效果 可控制分隔条的粗细和样式 可保存和恢复分...

匿名
2013/01/24
373
0

没有更多内容

加载失败,请刷新页面

加载更多

wasm cpp 传值

简单传递基础值 #include <emscripten.h>extern "C"{ int fib(int n);}int fib(int n){ return n < 2 ? n : fib(n - 1) + fib(n - 2);}int main(int argc, char......

阿豪boy
16分钟前
9
0
全球产业数字化转型趋势及方向研判

中国电子学会研究咨询中心主任、中国数字经济百人会秘书长李颋发布由中国数字经济百人会依托中国电子学会专业研究团队编制的《全球产业数字化转型趋势及方向研判》。该报告结合国内外领军企业...

Idea
17分钟前
0
0
再谈测试浮躁论——深度好文!

目前来说软件测试人员都有这么些问题吧,这大概已经成为中国目前测试的瓶颈了。人心浮躁大概不是某些职业人特有的,其实是我们这些年轻人的通病了。但身为测试人员,当你在应聘找工作的时候是...

程序员一凡
25分钟前
10
0
Spring Boot 教程 - 文件上传下载

在日常的开发工作中,基本上每个项目都会有各种文件的上传和下载,大多数文件都是excel文件,操作excel的JavaAPI我用的是apache的POI进行操作的,POI我之后会专门讲到。此次我们不讲如何操作...

Butterfly-Tri
今天
27
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部