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 4sudo make install
未出现任何编译错误,会成功编译出libphpx.so,并安装到系统的lib目录。头文件会复制到系统的include目录。这时需要执行 sudo ldconfig刷新so文件缓存。
0x02 新建工程
使用任意开发工具,新建一个http://test.cc源文件。首先需要引入phpx.h头文件。然后使用using引入phpx的命名空间。PHP官方未使用C++,因此phpx直接使用了php作为命名空间。
#include
using namespace std;
using namespace php;
创建扩展使用PHPX_EXTENSION宏来实现。在这宏中只需要new Extension即可创建扩展。构造方法接受2个参数,第一个是扩展的名称,第二个是扩展的版本号。在PHPX_EXTENSION宏中return这个扩展对象的指针。
PHPX_EXTENSION()
{
Extension*ext = new Extension("test", "0.0.1");returnext;
}
0x03 增加函数
一个PHP扩展的主要作用就是提供扩展函数,扩展函数由于是用C/C++代码实现,因此它的性能会比PHP用户函数性能高几十甚至上百倍。在phpx中实现函数非常简单。使用PHPX_FUNCTION来实现扩展函数,然后调用Extension::registerFunction来注册扩展函数。
这里我们的代码非常简单,cpp_test($str, $n),调用这个函数返回一个$n个$str的数组。
1 #include
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 returnext;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.cc8 c++ -DHAVE_CONFIG_H -g -o test.so -O0 -fPIC -shared test.cc -std=c++11 ${PHP_INCLUDE} -I${PHP_INCLUDE_DIR} -lphpx9
10 install: test.so11 cp test.so ${PHP_EXTENSION_DIR}/
12 clean:
13 rm *.so
php-config 这个工具是PHP提供的,使用php-config可以得到PHP的安装路径、头文件目录、扩展目录、其他额外的编译参数等等。
这个Makefile支持了3个指令,make编译,make clean清理,make install安装到扩展目录中。
编写好之后执行make install,就会编译扩展并将扩展test.so安装到PHP的扩展目录中。这时需要修改php.ini加入extension=test.so加载扩展。
使用php -m来观察你的扩展是否正常加载。
1 php -m2 [PHP Modules]3 Core4 ctype5 curl6 date
7 dom8 fileinfo9 filter10 gd11 hash12 iconv
13 inotify14 json15 libxml16 mbstring17 mcrypt18 memcached19 mongodb20 mysqli21 mysqlnd22 openssl23 pcntl24 pcre25 PDO26 pdo_mysql27 pdo_sqlite28 Phar29 posix30 redis31 Reflection32 session33 SimpleXML34 sockets35 SPL36 sqlite337 standard38 swoole39 test40 tokenizer41 xml42 xmlreader43 xmlwriter44 yac45 zlib46 zmq47
48 [Zend Modules]
这里看到test,表明你的扩展已经加载成功了,现在就可以调用cpp_test这个扩展函数了。
0x05 执行
编写一个test.php,内容为:
1 <?php2 var_dump(cpp_test("hello", 3));3 执行test.php:4
5 php test.php6 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实现扩展类、资源、回调函数等更复杂的功能。