php 类扩展,自己写PHP扩展之创建一个类

原文:http://www.imsiren.com/archives/572

比如我们要创建一个类..PHP代码如下

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

class Person {

public $name;

public $age;

public function __construct() {

echo "construct is running!

";

}

public function __destruct() {

echo "

destruct is running!";

}

public function getproperty($key) {

echo $this->$key;

}

public function setproperty($key,$val) {

$this->$key =$val;

}

}

用PHP来做,很简单..

那么用PHP扩展来写该怎么做?

OK.

1.在php_siren.h里面声明类

1

2

3

4

PHP_METHOD(Person,__construct);

PHP_METHOD(Person,__destruct);

PHP_METHOD(Person,setproperty);

PHP_METHOD(Person,getproperty);

PHP_METHOD宏.

PHP_METHOD 等于ZEND_METHOD

这个宏接受两个参数,第一个是类名,第二个是类的方法

1

2

3

4

#define ZEND_METHOD(classname, name)    ZEND_NAMED_FUNCTION(ZEND_MN(classname##_##name))

#define INTERNAL_FUNCTION_PARAMETERS int ht, zval *return_value, zval **return_value_ptr, zval *this_ptr, int return_v    alue_used TSRMLS_DC

//最后等于

void name(int ht, zval *return_value, zval **return_value_ptr, zval *this_ptr,int return_v    alue_used TSRMLS_DC )

这个宏是用来声明我们的方法…

2.设置接收的参数

我们的方法如果需要接受参数.那么就要执行

1

2

3

ZEND_BEGIN_ARG_INFO_EX(arg_person_info,0,0,2)

ZEND_ARG_INFO(0,name)

ZEND_END_ARG_INFO()

详细讲这几个宏之前先看看zend_arg_info

1

2

3

4

5

6

7

8

9

10

11

typedef struct _zend_arg_info {

const char *name;//参数名称

zend_uint name_len;//长度

const char *class_name;//所属类名

zend_uint class_name_len;//类名长度

zend_bool array_type_hint;

zend_bool allow_null;//允许为空

zend_bool pass_by_reference;//引用传值

zend_bool return_reference;//引用返回

int required_num_args;//参数个数

} zend_arg_info;

ZEND_BEGIN_ARG_INFO_EX定义在Zend/zend_API.h

1

2

3

#define ZEND_BEGIN_ARG_INFO_EX(name, pass_rest_by_reference, return_reference, required_num_args)       \

static const zend_arg_info name[] = ,

很明显 声明一个zend_arg_info的数组name,然后初始化结构体的值

ZEND_ARG_INFO(0,name)的定义如下

1

#define ZEND_ARG_INFO(pass_by_ref, name)  { #name, sizeof(#name)-1, NULL, 0, 0, 0, pass_by_ref, 0, 0 },

这三个宏 执行代码 等于

1

2

3

static const zend_arg_info name[] = ,

{ #name,sizeof(#name)-1, NULL, 0, 0, 0, pass_by_ref, 0, 0 },

};

3.创建zend_function_entry结构数组

1

2

3

4

5

6

7

const zend_function_entry person_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,getproperty,arg_person_info,ZEND_ACC_PUBLIC)

PHP_ME(Person,setproperty,arg_person_info,ZEND_ACC_PUBLIC)

PHP_FE_END

};

zend_function_entry定义如下

1

2

3

4

5

6

7

typedef struct _zend_function_entry {

const char *fname;//函数名称

void (*handler)(INTERNAL_FUNCTION_PARAMETERS);

const struct _zend_arg_info *arg_info;//参数

zend_uint num_args;//参数个数

zend_uint flags;//标示PUBLIC ?PRIVATE ?PROTECTED

} zend_function_entry;

PHP_ME宏接收四个参数

1 类名,

2 方法名,

3 zend_arg_info 的参数列表,

ZEND_ACC_PUBLIC ZEND_ACC_PRIVATE ZEND_ACC_PROTECTED是我们类里面的三个访问权限

ZEND_ACC_CTOR标示构造函数

ZEND_ACC_DTOR标示析构函数

4.修改PHP_MINIT_FUNCTION

前面我们说过 PHP_MINIT_FUNCTION是在模块启动的时候执行的函数

首先创建一个全局指针 zend_class_entry *person_ce;

在PHP_MINIT_FUNCTION加入如下代码

1

2

3

4

zend_class_entry person;

INIT_CLASS_ENTRY(person,"Person",person_functions);

person_ce=zend_register_internal_class_ex(&person,NULL,NULL TSRMLS_CC);

zend_declare_property_null(person_ce,ZEND_STRL("name"),ZEND_ACC_PUBLIC TSRMLS_CC);

1行创建一个zend_class_entry对象person.

zend_class_entry这个结构体前面也讲过 PHP内核研究之类的实现

2行初始化zend_class_entry 它执行了如下代码

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

30

31

可以对应文章>> PHP内核研究之类的实现来分析

zend_declare_property_null(person_ce,ZEND_STRL(“name”),ZEND_ACC_PUBLIC TSRMLS_CC);

创建一个值为NULL的属性

第一个参数是类名,第二个参数是 属性名称,第三个参数是属性名的长度,因为ZEND_STRL宏定义了长度,所以这里不用再传递长度.

第四个参数是属性的访问权限.

还有其他几个函数用来创建不同类型的属性

1

2

3

4

5

6

7

zend_declare_property_bool

zend_declare_property_double

zend_declare_property_ex

zend_declare_property_long

zend_declare_property_null

zend_declare_property_string

zend_declare_property_stringl

5.创建 php_siren.h头文件中的方法体

1

2

3

4

5

6

7

8

9

10

11

12

PHP_METHOD(Person,__construct){

php_printf("construct is running
");

}

PHP_METHOD(Person,__destruct){

php_printf("destruct is running
");

}

PHP_METHOD(Person,setproperty){

}

PHP_METHOD(Person,getproperty){

}

6.最后make&& make install

编译我们的扩展,

重新启动apache.

$p=new Person();

?>

我们就能在浏览器里看到输出的内容

construct is running

destruct is running

这样 ..我们用扩展创建的一个基本类就完成了.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值