2017年第三届PHP开发者大会总结(三)php-x篇.md

使用c++11开发php7扩展(韩天峰)

简单说就是天峰在多年的php扩展开发中,感受到基于c的zend api十分不方便,所以基于c++11对zend api进行了封装,既降低了php扩展的开发难度,提高了开发效率,同时也为php带了更多的想象空间,并把这个项目命名为php-x

什么是php扩展?

定义
php本身是c语言开发的,其实可以想象我们是使用php这个高级语言去驱动一个c开发的引擎(zend engine)去做事情的。php扩展就是允许我们使用c为整个引擎开发新的插件来扩展php的功能,比如网络请求的curl扩展,使用mysql的mysqli扩展等。这种机制有利于社区为php的发展添砖加瓦,可以说zend engine本身就是一个个插件堆积出来的

如何开发扩展?

  1. 使用ext_skel生成扩展开发骨架
  2. 编辑config.m4文件
  3. 在extension.h头文件中定义扩展函数
  4. 修改extension.c源文件,实现扩展函数逻辑
  5. 利用phpize configure make & make install安装扩展

这样当php程序中调用扩展函数时,zend引擎会去调用你所开发的扩展。当然,你在扩展逻辑中只能使用c语言通过zend api来对传入的php变量进行解析、处理,最终再通过zend api返回php变量,继续原流程

目前扩展开发有何痛点?

zend api不好用

  1. 大量使用宏
  2. api名称太长,参数太多,容易出错
  3. api分散在众多.h和.c文件中
  4. 需要精通c语言,大量的指针场景,容易出错
  5. 没有任何,任何的教程或手册!

古老的c语言

  1. 50年历史的古老编程语言
  2. 面向过程的风格,封装性差
  3. 指针容易出错
  4. 缺少原生的数据结构支持
  5. 仅适合编写底层软件

php-x做了哪些工作?

鉴于前面说的问题,php-x使用c++11对zend api进行了封装,选择c++11是因为

  1. c++是现代编程语言
  2. 面向对象风格,封装性好
  3. 模板泛型编程
  4. STL容器
  5. 通用编程,适用范围广

可以简单对比一下封装后的代码

// 变量操作
ZVAL_LONG(&a, 1234);    // zend api
Variant a = 1234;       // php-x

// 类型推断
Z_TYPE_P(value) == IS_LONG;    // zend api
value.isLong();                // php-x

// 类型转换
convert_to_long(value);    // zend api
value.toInt()              // php-x

此外,php-x还提供了数组、字典、资源等多种常见数据结构和方法封装。而且还提供了在c++中嵌套php的功能,c++中也可以访问诸如$_GET、$_POST等上下文,配合通过php扩展赋予了php调用c++的能力,实际上php-x完全打通了php与c++

实战php7扩展

本小节利用php-x实现一个扩展my_ext,包含my_ext_class类和my_ext_test函数,对php-x开发php7扩展做一个简单的示例

php7扩展注册

PHPX_EXTENSION() {
    Extension *extension = new Extension("my_ext", "0.0.1");
    extension->onStart = [extension]() {
        extension->registerConstant("MY_EXT_VERSION", "0.0.1");
        extension->registerClass(my_ext_class);
    };
    extension->registerFunction(PHPX_FN(my_ext_test));
    return extension;
}

实现扩展函数

PHPX_FUNCTION(my_ext_test) {
    for (int i = 0; i < args.count(); i++) {
        php::echo("arg[%d] type is %d\n", i, args[i].type());
    }
    
    Variant v1 = arg[0];
    Array arr(v1);
    arr.set(1, 'efg');

    retval = arr;
}

实现扩展类

Class *my_ext_class = new Class('myClass');
my_ext_class->addMethod(PHPX_ME(myClass, test), STATIC);
my_ext_class->addMethod(PHPX_ME(myClass, test2));
my_ext_class->addProperty('name', 'Rango');
extension->registerClass(my_ext_class);

实现类方法

PHPX_METHOND(myClass, test2) {
    Variant res = newResource('String', new String('hello'));
    _this.set('resource', res);
    php::error(E_WARNING, 'err message');
}

注册phpinfo

extension->info({'gtk support', 'enabled'}, {
    {'author', 'Rango'},
    {'version', ext->version},
});

然后和一般扩展一样编译安装就行

php的想象空间

php-x打通了php与c++,理论上c++可以做的事,php同样也能做到。同时php扩展的开发难度也大大降低,可以应用于更多的场景

  1. 可以用c++扩展实现多线程
  2. 程序中计算密集型部分可以轻松使用扩展实现
  3. 可以通过扩展加密商业软件
  4. Fackbook、Google、Microsoft、Tencent等巨头的开源c++库可以为php所用了

你可能感兴趣的:(2017年第三届PHP开发者大会总结(三)php-x篇.md)