`

PHP扩展实现类扩展

阅读更多

在第一篇文章中,我们所开发的扩展是单个函数,本篇文章看一下如何开发一个类扩展。假设我们要用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

分享到:
评论

相关推荐

    使用C++11开发PHP7扩展

    1. PHP 可以用 C++ 扩展实现多线程 2. PHP-X 支持 Windows 平台,可以开发Windows的PHP扩展 3. 程序中大量运算的逻辑可以改为 C++ 扩展实现 4. 使用 PHP-X 开发商业软件,避免源码泄漏

    thinkphp5框架实现的自定义扩展类操作示例

    本文实例讲述了thinkphp5框架实现的自定义扩展类操作。分享给大家供大家参考,具体如下: 1.在extend目录下新建要定义的扩展类:如下图所示 2.定义扩展类的内容 &lt;?php namespace org; /** * */ class Auth...

    php扩展imagick打文字水印、图片水印、裁剪、缩略图工具类

    比GD库更强大的imagick php扩展,运行效率实现效率更快

    仿照php的mysqli扩展自己使用MySQL的C Interface实现了一个简单的mysql操作类

    我仿照php的mysqli扩展自己使用MySQL的C Interface实现了一个简单的mysql操作类。这个类可以帮助我更方便地与MySQL数据库进行交互,并且让我更好地理解底层的操作原理。基于这个类,我写了一个简单的字符统计测试...

    PHP实现基于面向对象的mysqli扩展库增删改查操作工具类

    本文实例讲述了PHP实现基于面向对象的mysqli扩展库增删改查操作工具类。分享给大家供大家参考,具体如下: mysqli扩展库是MySQL扩展库的改进版本,在mysql扩展库的基础上提高了稳定性和效率,mysqli扩展库有两套东西...

    Thinkphp 框架扩展之Widget扩展实现方法分析

    本文实例讲述了Thinkphp 框架扩展之Widget扩展实现方法。分享给大家供大家参考,具体如下: Widget扩展 Widget扩展一般用于页面组件的扩展。 举个例子,我们在页面中实现一个分类显示的Widget,首先我们要定义一个...

    php实现下载图片的通用方法类

    一个php实现下载图片的通用方法类。获取图片的扩展名,不同的图片类型选择不同的图片生成和保存函数。

    Thinkphp 框架扩展之类库扩展操作详解

    本文实例讲述了Thinkphp 框架扩展之类库扩展操作。分享给大家供大家参考,具体如下: 类库扩展 ThinkPHP的类库主要包括公共类库和应用类库,都是基于命名空间进行定义和扩展的。只要按照规范定义,都可以实现自动...

    TimoPHP是一个简单、快速、规范、灵活、扩展性好的PHP类.zip

    1、PHP5.6 (支持PHP7) 2、PSR标准 3、轻量级,扩展灵活 4、自定义异常处理,如404 5、原生模版解析 6、支出视图组件 7、模板支持多主题、layout(布局) 8、写app接口还是挺爽的 9、加入对cli模式支出,...

    PHP使用SOAP扩展实现WebService的方法

    本文实例讲述了PHP使用SOAP扩展实现WebService的方法。分享给大家供大家参考,具体如下: 最近在一个PHP项目中对接外部接口涉及到WebService,搜索引擎上相关文章不是很多,找到的大都是引用一个号称很强大的开源...

    ext-fiber:PHP光纤扩展

    该扩展的安装与其他PHP扩展类似。 git clone https://github.com/amphp/ext-fiber cd ext-fiber phpize ./configure make make test make install 原料药 通过创建Fiber类的实例来制作Fiber 。 final class Fiber ...

    PHP关键词提取扩展acfilter.zip

    acfilter 是一个PHP扩展,您需要设定一个词库,然后检测任何一篇文章看它包含了词库中的哪些词. 应用场景:禁词屏蔽;SEO伪原创;当词库足够大时,可以成为一个简单的分词工具;准备一系列分类的词库,可以实现文本分类和...

    php分页类工具类

    这是一个功能强大,并且易于扩展的分页类,该类将分页的各个元素单独分开模块化,用户可以随心所欲的拼接出自己想要的分页效果,更是添加了控制分页样式的功能,可以让你独立设置分页各元素的样式,也集成了集中已经...

    phalcon-jdatetime-by-zephir:jDatetime (Hijri Shamsi Jalali Date) 作为由 zephir 语言提供支持的 PHP 扩展实现

    jDatetime (Hijri Shamsi / Jalali Date) 作为由 zephir 语言提供支持的 PHP 扩展实现 此扩展作为(扩展 Phalcon 框架)的一部分发布 要求 编译 zephir 解析器: (仅用于编译扩展) PHP 5.2+ 版权所有 (C) 2013...

    PHP 文件扩展名 获取函数

    有时候我们需要获取文件的扩展名,分类文件等原因,下面是php的函数实例代码。

    功能齐全的php验证类

    一个可扩展的功能齐全的php验证类, 类里面可以的各类验证可自行调整实现,现在为基本实现方式。 需要添加规则的话,直接定义方法,方法名即为规则名称。具体参考使用方法。

    php实现下载图片的通用方法类.zip

    介绍一个php实现下载图片的通用方法类。获取图片的扩展名,不同的图片类型选择不同的图片生成和保存函数。

    php5-fastcgi:PHP FastCGI扩展

    该扩展通过FastCGIApplication类为PHP应用程序提供了libfcgi的某些功能。正在安装以下这些说明用于在运行Ubuntu 64位服务器15.04的虚拟机上安装扩展。 sudo apt-get install ...

    PHP开发框架底层【试用于任何系统的PHP+mysql+smarty+oop开发】

    数据库可以实现新闻无限分类扩展,系统配置无限增加字段扩展 试用于任何系统的PHP+mysql+smarty+oop开发,一下是具体的结构图。 PHP100_F_System ┃ ┣━ admin ┃ ┣━ common ┃ ┃ ┣━ action.class.php...

Global site tag (gtag.js) - Google Analytics