为了操作一个对象,我们需要先获取这个对象的实例,而这有肯定会涉及调用对象的构造方法。首先我们先了解下一个object在PHP内核中到底是如何实现的。
01 | typedef struct _zend_object_value { |
02 | zend_object_handle handle; |
03 | zend_object_handlers *handlers; |
07 | typedef union _zvalue_value { |
15 | zend_object_value obj; |
如果我们有一个zval *tmp,那么tmp->value.obj来访问到最终保存对象实例的zend_object_value结构体,它包含两个成员:
- zend_object_handle handle:最终实现是一个unsigned int值,Zend会把每个对象放进数组里,这个handle就是此实例的索引。所以我们在把对象当作参数传递时,只不过是传递的handle罢了,这样对性能有利,同时也是对象的引用机制的原理。
- zend_object_handlers *handlers:这个里面是一组函数指针,我们可以通过它来对象进行一些操作,比如:添加引用、获取属性等。此结构体在Zend/zend_object_handlers.h里定义。
下面我给出这个类的PHP语言实现,让我们在扩展中实现它,并生成它。
04 | public function __construct() |
09 | public function hello() |
11 | echo "hello world!\n" ; |
下面我们在扩展中实现以上test_call函数。
01 | zend_class_entry *baby_ce; |
03 | ZEND_FUNCTION(test_call) |
07 | object_init_ex(obj, baby_ce); |
10 | walu_call_user_function(NULL, obj, "__construct" , "" ); |
12 | walu_call_user_function(NULL, obj, "hello" , "" ); |
17 | ZEND_METHOD(baby, __construct) |
19 | printf ( "a new baby!\n" ); |
22 | ZEND_METHOD(baby, hello) |
24 | printf ( "hello world!!!!!\n" ); |
27 | static zend_function_entry baby_method[]={ |
28 | ZEND_ME(baby, __construct, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR) |
29 | ZEND_ME(baby, hello, NULL, ZEND_ACC_PUBLIC) |
33 | ZEND_MINIT_FUNCTION(test) |
36 | INIT_CLASS_ENTRY(ce, "baby" , baby_method); |
37 | baby_ce = zend_register_internal_class(&ce TSRMLS_CC); |
没有帐号? 现在注册.