PHP扩展开发之创建一个类

运行环境:

  • php 7.1.10

PHP7.0以上版本和以下版本创建流程和使用的函数可能会有些差异

第一步,先生成一个扩展骨架

cd php-7.1.10
cd ext
./ext_skel --extname=classextension
vim classextension/config.m4

去掉前面的dnl

dnl PHP_ARG_ENABLE(.....

dnl [ --enable.....)

:wq退出并保存

第二步, 修改classextension.c, 比如我们要增加一个类名为Person, 并拥有一个静态成员函数叫say, 这个函数的作用就是打印给定的字符串到终端.

PHP_METHOD(Person, say)
{
    zend_string *message;

    ZEND_PARSE_PARAMETERS_START(1, 1)
        Z_PARAM_STR(message);
    ZEND_PARSE_PARAMTERS_END();

    php_printf("%s", (char *)ZSTR_VAL(message));

    RETURN_TRUE;
}

定义一个方法时, 我们使用PHP_METHOD宏, 这个宏有两个参数,类名和方法名。定义好了方法,PHP引擎如何知道你定义的方法需要几个参数呢?这个时候又要用到另外一个宏 ZEND_BEGIN_ARG_INFO_EX 对需要参数进行描述.

ZEND_BEGIN_ARG_INFO_EX(arginfo_say_message, 0, 0, 1)
    ZEND_ARG_INFO(0, message)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX有四个参数

  • 描述的名字
  • 扩展参数,暂时用不到
  • 是否返回引用
  • 必要的参数个数.

ZEND_ARG_INFO 有两个参数

  • 是否传递引用
  • 参数名

上面我们提到创建的方法为类的静态方法, 那PHP引擎如何知道这个方法为静态方法?定义一个函数实体集, 并使用PHP_ME宏.

const zend_function_entry classextension_functions[] = {
    PHP_ME(Person, say, arginfo_say_message, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
    PHP_FE_END;
};

PHP_ME有四个参数

  • 类名
  • 方法名
  • 参数信息
  • 方法的权限, 私有,公有或受保护等

最终把定义好的方法注册到PHP引擎中

PHP_MINIT_FUNCTION(classextension)
{
    zend_class_entry ce;
    INIT_CLASS_ENTRY(ce, "Person", classextension_functions);
    zend_register_internal_class(&ce);
    return SUCCESS;
}

我们的函数最终会被解析成下面这个样子:

void Person_say(zend_execute_data *execute_data, zval *return_value)
{
    zend_string *message;

    //这段太长了, 就不贴了
    ZEND_PARSE_PARAMETERS_START(1, 1)
        Z_PARAM_STR(message);
    ZEND_PARSE_PARAMTERS_END();

    php_printf("%s", (char *)ZSTR_VAL(message));

    do {
        (*return_value).u1.type_info = IS_TRUE;
        return;
    } while (0);
}

编译这个扩展, 并加入到php.ini

phpize
./configure && make && sudo make install

查找php.ini的位置

php -i | grep ini
# 一般ini文件在/usr/local/lib下
vim /usr/local/lib/php.ini
extension_dir = "扩展目录绝对路径"
extension=classextension.so

再运行php -m | grep classextension, 看看是否成功.
运行php -r "Person::say('hello');" 看看结果.

你可能感兴趣的:(php)