接下来我们要用扩展的形式实现以下类(演示环境:linux、php-5.5.34-src)

 <?php
class Person
{
private $_name;
public function getName()
{
return $this -> _name;
}
public function setName($name)
{
$this -> _name = $name;
}
}

在PHP源码目录下

 cd php-5.5.-src
cd ext
./ext_skel --extname=hdx //生成hdx扩展骨架
cd hdx

1.修改config.m4

PHP_ARG_WITH(hdx, for hdx support,
[ --with-hdx Include hdx support]) //把这两行前面的dnl去掉 大概在 10-12行

2.在hdx.h添加如下

PHP_METHOD(Person, __construct);
PHP_METHOD(Person, __destruct);
PHP_METHOD(Person, getName);
PHP_METHOD(Person, setName);

3.在hdx.c下方添加相应函数

 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"), TSRMLS_CC);
RETURN_STRING(Z_STRVAL_P(name), );
} 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, );
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()函数更新属性值。

4.在hdx.c 上方,初始化类:在扩展初始化函数中,注册并初始化类。

 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宏初始化类,第二个参数指定类名,第三个参数是函数表。

5. 注册到函数:声明方法的参数,并注册到函数表中。

 ZEND_BEGIN_ARG_INFO(arg_person_setname, )
ZEND_ARG_INFO(, 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:指定该方法为析构函数

6.安装

 /usr/local/php/bin/phpize
./configure --with-php-config=/usr/local/php/bin/php-config
make && make install

然后在PHP安装目录下修改php.ini把扩展添加上

7. 运行测试:编译安装扩展后,编写一段简单的测试脚本:

 <?php
$person = new Person();
$person->setName("huangdongxi");
echo $person->getName().'<br/>';

运行后可以看到如下输出,说明扩展工作正常:
__construct called.
huangdongxi
__destruct called.

PHP扩展开发之简单类开发的更多相关文章

  1. Android开发学习——简单类图

    1.类A继承于类B    (B 是父类,A是 子类) 2.小汽车.自行车 实现车的接口 3.A中有B这个成员变量,单向关联 4.聚合,整体与部分的关系.has-a  B中的构造函数(或set方法)需要 ...

  2. PHP扩展开发-简单类扩展

    今天来学习简单类扩展开发 实现目标为如下php的类 <?php class classext(){ private $username; CONST URL="http://www.g ...

  3. 3.NetDh框架之缓存操作类和二次开发模式简单设计(附源码和示例代码)

    前言 NetDh框架适用于C/S.B/S的服务端框架,可用于项目开发和学习.目前包含以下四个模块 1.数据库操作层封装Dapper,支持多种数据库类型.多库实例,简单强大: 此部分具体说明可参考博客: ...

  4. 用扩展开发一个PHP类

    原文:http://my.oschina.net/mickelfeng/blog/122519?p=1 假设我们要用PHP扩展实 现一个类Person,它有一个private的成员变量$_name和两 ...

  5. php扩展开发3--扩展类传参数

    1.需要实现的细节 实现一个person类 ,实现一个doing方法和saying方法 在构造方法中传递一个数组,在doing中打印此数组 saying方法中,构建一个空数组,返回,不需要传参. 2. ...

  6. php扩展开发2--添加类

    1.需要实现的细节 实现一个person类 实现一个doing方法和saying方法 2.第一个扩展 2.1创建类的扩展: [root@bogon ext]# cd /usr/local/src/ph ...

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

    开篇:每当我们将开发好的ASP.NET网站部署到IIS服务器中,在浏览器正常浏览页面时,可曾想过Web服务器是怎么工作的,其原理是什么?“纸上得来终觉浅,绝知此事要躬行”,于是我们自己模拟一个简单的W ...

  8. MVVM开发模式简单实例MVVM Demo

    本文主要是翻译Rachel Lim的一篇有关MVVM模式介绍的博文 A Simple MVVM Example 并具体给出了一个简单的Demo(原文是以WPF开发的,对于我自己添加或修改的一部分会用红 ...

  9. Oracle数据库中调用Java类开发存储过程、函数的方法

    Oracle数据库中调用Java类开发存储过程.函数的方法 时间:2014年12月24日  浏览:5538次 oracle数据库的开发非常灵活,不仅支持最基本的SQL,而且还提供了独有的PL/SQL, ...

随机推荐

  1. (原)ubuntu上安装Torch7及nn及dpnn

    转载请注明出处: http://www.cnblogs.com/darkknightzh/p/5653864.html 参考网址: http://torch.ch/docs/getting-start ...

  2. (转)android ndk 给结构体赋值的方法

    转自:http://www.cnweblog.com/fly2700/archive/2012/03/21/320083.html 1,java 代码 结构体定义 public class Media ...

  3. iconv编码转换指令

    看到一个不错的指令iconv,可以对文件编码进行转换,记录如下: iconv --list 列出所有支持转换的编码 icon -f code1 -t code2 filename -o newfile ...

  4. YUI Array 之some(检测|any)

    YUI原码 YUI someYArray.some = Lang._isNative(Native.some) ? function (array, fn, thisObj) { return Nat ...

  5. 写jQuery插件时,一种更好的合并参数的方法

    看到很多人写jQuery插件时居然这样合并参数: this.defaults = { 'color': 'red', 'fontSize': '12px', 'textDecoration':'non ...

  6. [Head First Python]6. 定制数据对象:打包代码与数据

    相同功能,演进实现 数据文件 sarah2.txt sarah Sweeney,2002-6-17,2:58,2.58,2:39,2-25,2-55,2:54,2.18,2:55,2:55 1- 返回 ...

  7. python----抽象类

    #!/usr/local/python3.5/bin/python3.5 ####实现方法一 class Supper(object): def delegate(self): self.action ...

  8. 添加事件监听兼容IE6-8

    IE8一下浏览器不支持addEventListener,用attachEvent取而代之,但是在时间类型前面要加上’on‘,例如click时间在attachEvent中要写成onclick. var ...

  9. hdu 1500 Chopsticks

    http://acm.hdu.edu.cn/showproblem.php?pid=1500 dp[i][j]为第i个人第j个筷子. #include <cstdio> #include ...

  10. 段(SEGMENT)

    伪指令SEGMENT被用来声明一个普通段.一个再定位类型(relocation type)和一个地址分配类型(allocation type)可以按如下形式指明: segment SEGMENT cl ...