用扩展开发一个PHP类

原文:http://my.oschina.net/mickelfeng/blog/122519?p=1

假设我们要用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.
时间: 2024-07-29 14:53:32

用扩展开发一个PHP类的相关文章

【Android开发VR实战】三.开发一个寻宝类VR游戏TreasureHunt

转载请注明出处:http://blog.csdn.net/linglongxin24/article/details/53939303 本文出自[DylanAndroid的博客] [Android开发VR实战]三.开发一个寻宝类VR游戏TreasureHunt VR即Virtual Reality虚拟现实.虚拟现实技术是一种可以创建和体验虚拟世界的计算机仿真系统它利用计算机生成一种模拟环境是一种多源信息融合的交互式的三维动态视景和实体行为的系统仿真使用户沉浸到该环境中. 那么,如何在Androi

php扩展开发2--添加类

1.需要实现的细节 实现一个person类 实现一个doing方法和saying方法 2.第一个扩展 2.1创建类的扩展: [[email protected] ext]# cd /usr/local/src/php-7.0.3/ext [[email protected] ext]# ./ext_skel --extname=person   //运行ext_skel创建扩展的开发包 2.2 修改配置 [[email protected] ext]# vim person/config.m4

PHP扩展开发之简单类开发

接下来我们要用扩展的形式实现以下类(演示环境:linux.php-5.5.34-src) 1 <?php 2 class Person 3 { 4 private $_name; 5 public function getName() 6 { 7 return $this -> _name; 8 } 9 public function setName($name) 10 { 11 $this -> _name = $name; 12 } 13 } 在PHP源码目录下 1 cd php-5

[原创]快速开发一个PHP扩展

http://blog.csdn.net/taft/article/details/596291 http://blog.csdn.net/heiyeshuwu/article/details/3453854 [原创]快速开发一个PHP扩展,布布扣,bubuko.com

HBase概念学习(八)开发一个类twitter系统之表设计

这边文章先将可能的需求分析一下,设计出HBase表,下一步再开始编写客户端代码. TwiBase系统 1.背景 为了加深HBase基本概念的学习,参考HBase实战这本书实际动手做了这个例子. 2.需求 这是一个用户推特系统,用户登陆到系统,需要维护用户的基本信息,然后用户可以发帖和其他用户进行互动.用户之间可以相互关注,用户可以浏览关注用户的推文等等. 这是一个比较简单的推特系统,不考虑用户之间的私信,用户评论推特等功能. 3.概要设计 3.1表设计 首先需要设计三个表:用户表,推特表以及用户

开发一个小的php扩展

今天试了一下在php添加扩展,看了挺多资料,细节上不一致,其他大体是差不多的. 我们来开发一个叫ccvita_string的函数,他的主要作用是返回一段字符,对应的php代码可能如此: function ccvita_string($str){ $result = '<a href="'.$str.'">Link</a>': return $result; }即生成链接 第一步,生成代码 进入php源代码中自带的工具ext_skel,利用其创建文件. 首先我们创

visual Studio 2017 扩展开发(一)《向Visual Studio菜单栏新增一个菜单》

最近有接触到关于visual studio 2017 扩展的开发,特此记录,也是为了督促自己去深入了解其原理. 开始开发Visual Studio 扩展,在这里我安装了visual studio 2017, 在安装的时候记得勾选上visual studio 扩展开发. 创建一个项目 我们打开编译器,文件→新建项目,模板→Visual C#→Extensibility 选择 VSIX Project.创建一个项目. 添加自定义命令 右键项目,添加新项.Visual C#项→Extensibilit

NX二次开发-UFUN获取一个图层类别的tag UF_LAYER_ask_category_tag

1 NX11+VS2013 2 3 #include <uf.h> 4 #include <uf_ui.h> 5 #include <uf_layer.h> 6 7 8 9 UF_initialize(); 10 11 //获取一个图层类别的tag 12 tag_t category = NULL_TAG; 13 UF_LAYER_ask_category_tag("01.Tangkl_Solids", &category); 14 15 /

自己动手模拟开发一个简单的Web服务器

开篇:每当我们将开发好的ASP.NET网站部署到IIS服务器中,在浏览器正常浏览页面时,可曾想过Web服务器是怎么工作的,其原理是什么?“纸上得来终觉浅,绝知此事要躬行”,于是我们自己模拟一个简单的Web服务器来体会一下. 一.请求-处理-响应模型 1.1 基本过程介绍 每一个HTTP请求都会经历三个步凑:请求-处理-响应:每当我们在浏览器中输入一个URL时都会被封装为一个HTTP请求报文发送到Web服务器,而Web服务器则接收并解析HTTP请求报文,然后针对请求进行处理(返回指定的HTML页面