用扩展开发一个PHP类
2016-05-04 16:59
232 查看
原文:http://my.oschina.net/mickelfeng/blog/122519?p=1
假设我们要用PHP扩展实 现一个类Person,它有一个private的成员变量$_name和两个public的实例方法getName()和setName(),可以用 PHP代码表示如下:
?
1. 声明方法:还使用第一篇文章里面用过的示例,首先在头文件php_fetion_echo.h里加入方法声明。
前面的扩展在声明函数时使用PHP_FUNCTION宏,而在实现类扩展时我们使用PHP_METHOD宏,第一个参数指定类名,第二个参数指定方法名。
2. 方法实现:在fetion_echo.c文件中实现这几个方法,构造函数和析构函数中只是输出一些文本。
?
对上面的代码做一些解释:
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. 初始化类:在扩展初始化函数中,注册并初始化类。
使用INIT_CLASS_ENTRY宏初始化类,第二个参数指定类名,第三个参数是函数表。
4. 注册到函数:声明方法的参数,并注册到函数表中。
类方法参数的声明与之前我们函数参数声明方式一致,在注册类方法到函数表中时使用PHP_ME宏,而不是之前使用的PHP_FE宏。
ZEND_ACC_PUBLIC:指定方法的访问修饰符
ZEND_ACC_CTOR:指定该方法为构造函数
ZEND_ACC_DTOR:指定该方法为析构函数
5. 运行测试:编译安装扩展后,编写一段简单的测试脚本:
运行后可以看到如下输出,说明扩展工作正常:
假设我们要用PHP扩展实 现一个类Person,它有一个private的成员变量$_name和两个public的实例方法getName()和setName(),可以用 PHP代码表示如下:
?
PHP_METHOD(Person, __construct); PHP_METHOD(Person, __destruct); PHP_METHOD(Person, getName); PHP_METHOD(Person, setName);
前面的扩展在声明函数时使用PHP_FUNCTION宏,而在实现类扩展时我们使用PHP_METHOD宏,第一个参数指定类名,第二个参数指定方法名。
2. 方法实现:在fetion_echo.c文件中实现这几个方法,构造函数和析构函数中只是输出一些文本。
?
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); return SUCCESS; }
使用INIT_CLASS_ENTRY宏初始化类,第二个参数指定类名,第三个参数是函数表。
4. 注册到函数:声明方法的参数,并注册到函数表中。
ZEND_BEGIN_ARG_INFO(arg_person_setname, 0) ZEND_ARG_INFO(0, name) ZEND_END_ARG_INFO() const zend_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. 运行测试:编译安装扩展后,编写一段简单的测试脚本:
<?php $person = new Person(); $person->setName("mickelfeng"); echo $person->getName().'<br/>';
运行后可以看到如下输出,说明扩展工作正常:
__construct called. mickelfeng __destruct called.
相关文章推荐
- PHP之命名空间
- 简单好用的时间插件laydate实现开始时间和结束时间的限制
- php 删除文件夹里的图片
- PHP学习笔记——面向对象编程
- laravel框架知识点记录
- 1.live555源码分析----RSTPServer创建过程分析
- PHPCMS手机站点配置
- PHP语言 -- 权限
- xampp无法打开phpmyadmin解决方案
- TP框架实现分页
- php环境配置
- PHP随机数 C扩展随机数
- php访问msSqlServer还是用odbc方式好
- Windows Server 2012无法开启FTP服务器解决办法
- 用FileInputStream和FileOutPutStream读写文件
- PHP中间件--ICE
- tp框架中使用phpexcel导出excel表格
- YII 学习之修改默认控制器
- 每天laravel-20160730| Container -2
- FTP断点续传