在第一篇文章中,我们所开发的扩展是单个函数,本篇文章看一下如何开发一个类扩展。假设我们要用PHP扩展实 现一个类Person,它有一个private的成员变量$_name和两个public的实例方法getName()和setName(),可以用 PHP代码表示如下:
1
2
3
4
5
6
7
8
9
10
11
12
|
<?php class Person
{ 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文件中实现这几个方法,构造函数和析构函数中只是输出一些文本。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
PHP_METHOD(Person, __construct) { php_printf( "__construct called." );
} PHP_METHOD(Person, __destruct) { php_printf( "__destruct called.<br/>" );
} 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); 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 Extension开发内容,如INI设置,全局变量,参数传递等。
http://my.oschina.net/mickelfeng/blog/122519?p=1
相关推荐
1. PHP 可以用 C++ 扩展实现多线程 2. PHP-X 支持 Windows 平台,可以开发Windows的PHP扩展 3. 程序中大量运算的逻辑可以改为 C++ 扩展实现 4. 使用 PHP-X 开发商业软件,避免源码泄漏
本文实例讲述了thinkphp5框架实现的自定义扩展类操作。分享给大家供大家参考,具体如下: 1.在extend目录下新建要定义的扩展类:如下图所示 2.定义扩展类的内容 <?php namespace org; /** * */ class Auth...
比GD库更强大的imagick php扩展,运行效率实现效率更快
我仿照php的mysqli扩展自己使用MySQL的C Interface实现了一个简单的mysql操作类。这个类可以帮助我更方便地与MySQL数据库进行交互,并且让我更好地理解底层的操作原理。基于这个类,我写了一个简单的字符统计测试...
本文实例讲述了PHP实现基于面向对象的mysqli扩展库增删改查操作工具类。分享给大家供大家参考,具体如下: mysqli扩展库是MySQL扩展库的改进版本,在mysql扩展库的基础上提高了稳定性和效率,mysqli扩展库有两套东西...
本文实例讲述了Thinkphp 框架扩展之Widget扩展实现方法。分享给大家供大家参考,具体如下: Widget扩展 Widget扩展一般用于页面组件的扩展。 举个例子,我们在页面中实现一个分类显示的Widget,首先我们要定义一个...
一个php实现下载图片的通用方法类。获取图片的扩展名,不同的图片类型选择不同的图片生成和保存函数。
本文实例讲述了Thinkphp 框架扩展之类库扩展操作。分享给大家供大家参考,具体如下: 类库扩展 ThinkPHP的类库主要包括公共类库和应用类库,都是基于命名空间进行定义和扩展的。只要按照规范定义,都可以实现自动...
1、PHP5.6 (支持PHP7) 2、PSR标准 3、轻量级,扩展灵活 4、自定义异常处理,如404 5、原生模版解析 6、支出视图组件 7、模板支持多主题、layout(布局) 8、写app接口还是挺爽的 9、加入对cli模式支出,...
本文实例讲述了PHP使用SOAP扩展实现WebService的方法。分享给大家供大家参考,具体如下: 最近在一个PHP项目中对接外部接口涉及到WebService,搜索引擎上相关文章不是很多,找到的大都是引用一个号称很强大的开源...
该扩展的安装与其他PHP扩展类似。 git clone https://github.com/amphp/ext-fiber cd ext-fiber phpize ./configure make make test make install 原料药 通过创建Fiber类的实例来制作Fiber 。 final class Fiber ...
acfilter 是一个PHP扩展,您需要设定一个词库,然后检测任何一篇文章看它包含了词库中的哪些词. 应用场景:禁词屏蔽;SEO伪原创;当词库足够大时,可以成为一个简单的分词工具;准备一系列分类的词库,可以实现文本分类和...
这是一个功能强大,并且易于扩展的分页类,该类将分页的各个元素单独分开模块化,用户可以随心所欲的拼接出自己想要的分页效果,更是添加了控制分页样式的功能,可以让你独立设置分页各元素的样式,也集成了集中已经...
jDatetime (Hijri Shamsi / Jalali Date) 作为由 zephir 语言提供支持的 PHP 扩展实现 此扩展作为(扩展 Phalcon 框架)的一部分发布 要求 编译 zephir 解析器: (仅用于编译扩展) PHP 5.2+ 版权所有 (C) 2013...
有时候我们需要获取文件的扩展名,分类文件等原因,下面是php的函数实例代码。
一个可扩展的功能齐全的php验证类, 类里面可以的各类验证可自行调整实现,现在为基本实现方式。 需要添加规则的话,直接定义方法,方法名即为规则名称。具体参考使用方法。
介绍一个php实现下载图片的通用方法类。获取图片的扩展名,不同的图片类型选择不同的图片生成和保存函数。
该扩展通过FastCGIApplication类为PHP应用程序提供了libfcgi的某些功能。正在安装以下这些说明用于在运行Ubuntu 64位服务器15.04的虚拟机上安装扩展。 sudo apt-get install ...
数据库可以实现新闻无限分类扩展,系统配置无限增加字段扩展 试用于任何系统的PHP+mysql+smarty+oop开发,一下是具体的结构图。 PHP100_F_System ┃ ┣━ admin ┃ ┣━ common ┃ ┃ ┣━ action.class.php...