zoukankan      html  css  js  c++  java
  • 如何基于 PHP-X 快速开发一个 PHP 扩展

    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 新建工程

    使用任意开发工具,新建一个源文件。首先需要引入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实现扩展类、资源、回调函数等更复杂的功能。

  • 相关阅读:
    oracle-Oracle试题
    webservice-WebService试题
    php-PHP试题
    xml-xml试题
    ajax-Ajax试题
    用java在客户端读取mongodb中的数据并发送至服务器
    表格标记
    HTML常用标记
    Java操作Mongodb 保存/读取java对象到/从mongodb
    Spark Streaming的编程模型
  • 原文地址:https://www.cnblogs.com/a609251438/p/11806117.html
Copyright © 2011-2022 走看看