`

请您先登录,才能继续操作

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

分享到:
评论

相关推荐

    php intl扩展文件

    PHP的intl扩展是用于提供国际化(i18n)和本地化(l10n)功能的一个关键组件,尤其在处理多语言环境和全球化应用时非常有用。它包含了许多国际化库,如Collator(比较字符串),NumberFormatter(格式化数字和货币)...

    php扩展开发与内核应用

    9. 面向对象编程:在PHP扩展中实现面向对象编程,包括zend_class_entry结构体的使用,定义类和接口,以及类的继承和接口的实现。 10. 启动与终止的那点事:介绍扩展在启动和终止时要做的一些工作,如生命周期管理,...

    PHP5.6版本安装redis扩展(内附扩展包文件)

    可以通过实例化`Redis`类时传递参数实现。 总结,安装PHP5.6的Redis扩展涉及下载扩展源码,编译安装,修改配置文件,重启服务以及进行测试。同时,了解如何启用其他相关扩展,如`igbinary`,能提升Redis的性能。...

    ecshop指扩展分类

    至于`改过的文件`,它可能是指在使用这些功能过程中,商家可能修改过的系统文件,例如修改了与扩展分类相关的PHP脚本,以实现特定的业务需求或优化性能。 在实际应用中,熟悉并熟练运用ECShop的扩展分类和批量操作...

    php扩展学习PDF

    2. **PHP扩展基础**:讲解如何创建一个简单的PHP扩展,包括定义函数、类、常量等,以及如何编译和安装扩展。 3. **资源管理**:讨论如何管理和释放PHP扩展中使用的内存,避免内存泄漏和其他资源管理问题。 4. **...

    VC 建立php扩展

    3. **创建扩展**:根据需求编写C/C++代码,实现PHP扩展的功能。这包括定义PHP函数、类或者常量,以及处理数据类型转换等。 4. **编译扩展**:使用VC编译器将源代码编译成动态链接库(DLL)。这通常通过运行“nmake”...

    简单高性能优雅的phpc扩展框架

    2. **理解PHP扩展结构**:学习如何定义函数、类、常量和资源,以及如何与PHP的内存管理、错误处理和类型系统交互。 3. **编写C代码**:根据需求编写C语言实现的功能,遵循框架的约定和最佳实践。 4. **编译和测试**...

    php扩展开发流程,很详细

    PHP扩展开发流程是PHP开发者深入理解其内部机制和增强功能的重要途径。以下是一个详细的步骤指南,帮助你了解如何从头开始构建一个PHP扩展。 一、准备环境 1. 安装VC++ 6:这是微软的Visual C++ 6.0编译器,用于...

    windows php memcache 扩展

    在Windows操作系统上配置PHP与Memcache的扩展,可以实现PHP应用程序与Memcache服务的高效交互。 **1. 安装PHP Memcache扩展** Windows环境下,安装PHP Memcache扩展主要涉及以下步骤: - 首先,确保你的PHP版本与...

    cygwin windown php扩展开发工具

    在Windows环境下进行PHP扩展开发,通常开发者会遇到各种平台差异问题,因为PHP主要设计于类Unix系统,如Linux。然而,Cygwin提供了一个在Windows上运行Linux/Unix应用程序的解决方案,它创建了一个兼容层,使得...

    php的icu扩展下载

    一旦`intl`扩展启用,开发者就可以在PHP代码中使用`IntlDateFormatter`、`NumberFormatter`等类来处理日期、时间、货币和数字的格式化,还可以使用`Collator`类进行字符串比较和排序,从而满足国际化应用的需求。...

    PHP-REDIS扩展

    使用PHP-REDIS扩展非常直观,通过创建一个`Redis`类的实例并调用其方法来执行操作。例如,连接到Redis服务器: ```php $redis = new Redis(); $redis-&gt;connect('127.0.0.1', 6379); ``` 存储和检索数据也很...

    PHP扩展开发及内核应用

    通过学习PHP扩展开发,开发者可以创建自定义的函数、类和接口,甚至能够直接影响PHP的内存管理和执行流程。 在PHP扩展开发过程中,了解PHP的ZEND引擎是至关重要的。ZEND引擎是PHP的执行核心,它负责解析PHP代码,将...

    PHP扩展开发中文教程

    《PHP扩展开发中文教程》是一本专为对PHP扩展开发感兴趣的开发者量身打造的指南。这本书深入浅出地讲解了如何构建PHP的C语言扩展,从而增强PHP的功能和性能。PHP作为一种广泛使用的开源脚本语言,其核心在于其丰富的...

    PHP扩展开发.pdf

    在深入分析PHP扩展开发的知识点之前,首先需要了解什么是SAPI以及其作用。SAPI全称为Server API,是PHP与外部环境交互的接口,它抽象了复杂的外部环境,为PHP内部实现提供了一套固定的、统一的接口,从而让PHP能够不...

    php5.6+pdo+sqlserver 扩展dll

    本知识点主要围绕标题"php5.6+pdo+sqlserver 扩展dll"展开,讲解如何在PHP 5.6环境下通过PDO(PHP Data Objects)扩展来实现与SQL Server的连接,并使用相关的DLL扩展文件。 PDO是一种PHP的数据库抽象层,它提供了...

    PHP内核扩展教程及文档_ppt_code等

    4. **VLD(Visualize PHP's Zend opcodes)**:VLD是一个PHP扩展,用于可视化Zend引擎的opcode,这些opcode是PHP源代码被编译后的中间表示形式。理解opcodes有助于优化PHP代码和调试。 5. **运行栈(Execution ...

    php7-sqlserver扩展.zip

    在使用PHP7-SQLServer扩展时,你可以利用以下关键函数和类: - **sqlsrv_connect()**:创建到SQL Server的连接。 - **sqlsrv_query()**:执行SQL查询并返回结果集。 - **sqlsrv_fetch_array()**:从结果集中获取一...

    PHP5.4redis 扩展文件

    一旦扩展安装并启用,你就可以通过PHP的Redis类来操作Redis实例。以下是一些基本操作示例: ```php $redis = new Redis(); $redis-&gt;connect('127.0.0.1', 6379); // 连接到本地的Redis服务器 // 设置键值对 $redis...

Global site tag (gtag.js) - Google Analytics