博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
php扩展种类,PHP扩展实现类扩展 - mickelfeng的个人空间 - OSCHINA - 中文开源技术交流社区...
阅读量:6915 次
发布时间:2019-06-27

本文共 2813 字,大约阅读时间需要 9 分钟。

在第一篇文章中,我们所开发的扩展是单个函数,本篇文章看一下如何开发一个类扩展。假设我们要用PHP扩展实 现一个类Person,它有一个private的成员变量$_name和两个public的实例方法getName()和setName(),可以用 PHP代码表示如下:

{

private $_name;

public function getName()

{

return $this -> _name;

}

public function setName($name)

{

$this -> _name = $name;

}

}

1. 声明方法:还使用第一篇文章里面用过的示例,首先在头文件php_fetion_echo.h里加入方法声明。

PHP_METHOD(Person, __construct);

PHP_METHOD(Person, __destruct);

PHP_METHOD(Person, getName);

PHP_METHOD(Person, setName);

前面的扩展在声明函数时使用PHP_FUNCTION宏,而在实现类扩展时我们使用PHP_METHOD宏,第一个参数指定类名,第二个参数指定方法名。

2. 方法实现:在fetion_echo.c文件中实现这几个方法,构造函数和析构函数中只是输出一些文本。

PHP_METHOD(Person, __construct) {

php_printf("__construct called.");

}

PHP_METHOD(Person, __destruct) {

php_printf("__destruct called.

");

}

PHP_METHOD(Person, getName) {

zval *self, *name;

self = getThis();

name = zend_read_property(Z_OBJCE_P(self), self, ZEND_STRL("_name"), 0 TSRMLS_CC);

RETURN_STRING(Z_STRVAL_P(name), 0);

}

PHP_METHOD(Person, setName) {

char *arg = NULL;

int arg_len;

zval *value, *self;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) {

WRONG_PARAM_COUNT;

}

self = getThis();

MAKE_STD_ZVAL(value);

ZVAL_STRINGL(value, arg, arg_len, 0);

SEPARATE_ZVAL_TO_MAKE_IS_REF(&value);

zend_update_property(Z_OBJCE_P(self), self, ZEND_STRL("_name"), value TSRMLS_CC);

RETURN_TRUE;

}

对上面的代码做一些解释:

A. 获取方法的参数信息,仍然使用zend_parse_parameters函数,与之前我们介绍过的一样;

B. 获取this指针(相对于PHP代码而言,在PHP扩展中仍然使用zval结构表示)使用getThis()函数;

C. 使用MAKE_STD_ZVAL宏申请并初始化一个zval结构,在PHP扩展中,所有的数据类型其实都是用zval结构来表示的,在本系列文章中我会单独写一篇来介绍zval。

D. 获取属性值使用zend_read_property()函数,使用zend_update_property()函数更新属性值。

3. 初始化类:在扩展初始化函数中,注册并初始化类。

zend_class_entry *person_ce;

PHP_MINIT_FUNCTION(fetion_echo)

{

zend_class_entry person; INIT_CLASS_ENTRY(person, "Person", fetion_echo_functions);

person_ce = zend_register_internal_class_ex(&person, NULL, NULL TSRMLS_CC);

zend_declare_property_null(person_ce, ZEND_STRL("_name"), ZEND_ACC_PRIVATE TSRMLS_CC); returnSUCCESS;

}

使用INIT_CLASS_ENTRY宏初始化类,第二个参数指定类名,第三个参数是函数表。

4. 注册到函数:声明方法的参数,并注册到函数表中。

ZEND_BEGIN_ARG_INFO(arg_person_setname, 0)

ZEND_ARG_INFO(0, name)

ZEND_END_ARG_INFO() constzend_function_entry fetion_echo_functions[] = {

PHP_ME(Person, __construct, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)

PHP_ME(Person, __destruct, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_DTOR)

PHP_ME(Person, getName, NULL, ZEND_ACC_PUBLIC)

PHP_ME(Person, setName, arg_person_setname, ZEND_ACC_PUBLIC)

{NULL, NULL, NULL} /* Must be the last line in fetion_echo_functions[] */};

类方法参数的声明与之前我们函数参数声明方式一致,在注册类方法到函数表中时使用PHP_ME宏,而不是之前使用的PHP_FE宏。

ZEND_ACC_PUBLIC:指定方法的访问修饰符

ZEND_ACC_CTOR:指定该方法为构造函数

ZEND_ACC_DTOR:指定该方法为析构函数

5. 运行测试:编译安装扩展后,编写一段简单的测试脚本:

$person->setName("mickelfeng"); echo$person->getName().'

';

运行后可以看到如下输出,说明扩展工作正常:

__construct called.

mickelfeng

__destruct called.

在后面的文章,我会介绍更详细介绍PHP Extension开发内容,如INI设置,全局变量,参数传递等。

转载地址:http://rjncl.baihongyu.com/

你可能感兴趣的文章
天猫与九大快递合作 价格热战之后的冷静竞争
查看>>
git pull force
查看>>
scons用户手册
查看>>
使用new操作符来调用一个构造函数的时候发生了什么
查看>>
element-ui之el-scrollbar源码解析学习
查看>>
ceph 的pg诊断
查看>>
交换机配置vlan 访问控制列表
查看>>
我的友情链接
查看>>
12个时间管理妙招
查看>>
Python面向对象之类的成员
查看>>
Win8上iis配置
查看>>
Confluence 6 配置 Office 转换器
查看>>
IT从业人员关注哪些问题
查看>>
Windows 2012 Hyper –V 3.0 New Functions
查看>>
maven部分插件配置demo
查看>>
Grin交易原理详解
查看>>
大数据体系【概念认知】系列-2:存储以及副本策略
查看>>
我的友情链接
查看>>
linux企业常用服务---haproxy+nginx搭建web高可用集群
查看>>
win7 断开 共享连接的操作方法
查看>>