自己寫PHP延伸之操作類的屬性和方法
類建立好了..
那麼類肯定不止這些東西,它由繼承,屬性,返回值等.
1.方法的參數.
有方法,該方法就可能要有參數.參數是如何傳遞過來的呢?
如果看過之前的文章.那麼你肯定就知道了..是的 與普通函數的參數相同.
聲明char類型的指標用來儲存參數的值.
聲明int類型的變量來儲存的參數長度
然後用到 zend_parse_parameters函數
zend_parse_parameters(“,`< char *type_spec>`,`< …>`)
該參數有幾個重要的參數
第一個是參數的個數
第二個比較重要,它指定接收參數的類型
下面這份清單完整地列舉出了我們可以指定接收的參數類型:
l – 長整數
d – 雙精度浮點數
s – 字串 (也可能是空位元組)和其長度
b – 布林值
r – 資源, 儲存在 zval*
a – 陣列, 儲存在 zval*
o – (任何類的)對像, 儲存在 zval*
O – (由class entry 特殊的類的)對像, 儲存在 zval*
z – 實際的 zval*
下面的一些字元在類型說明字串(就是那個 char *type_spec)中具有特別的含義:
| – 顯示剩下的參數都是可選參數。如果使用者沒有傳進來這些參數值,那麼這些值就會被起始化成預設值。
/ – 顯示參數解析函數將會對剩下的參數以 SEPARATE_ZVAL_IF_NOT_REF() 的模式來提供這個參數的一份覆制,除非這些參數是一個引用。
! – 顯示剩下的參數容許被設定為 NULL(僅用在 a、o、O、r和z身上)。如果使用者傳進來了一個 NULL 值,則存儲該參數的變量將會設定為 NULL。
函數 get接收兩個參數 ,第一個參數是必填字串類型,第二個參數是可選為整型.
PHP代碼如下
1
2
3
function get($name,$age=0){
}
如果要在延伸裡實現這樣的功能,zend_parse_parameters的使用如下
char* name;
int name_length;
int age;
int age_length;
zend_parse_parameters(ZEND_NUM_ARGS ,」s|l」,&name,&name_length,&age,&age_len)
zend_parse_parameters 執行失敗的話會返回FAILURE.
執行完成後,name就是第一個參數的值,age就是第二個參數的值
我們甚至可以呼叫php_printf函數來輸出.
2.類的屬性
這類的內容在上一篇文章中其實已經講清楚了.
用zend_declare_property_*一系列函數來建立我們的屬性.當然是在PHP_MINIT_FUNCTION函數中建立
以 zend_declare_property_null為例:
zend_declare_property_null(“,`< char *name>`,`< int name_length>`,`< int access_type TSRMLS_DC>`)
ce :是一個zend_class_entry的指標.
name :是屬性的名稱
length :屬性名稱的長度
access_type:屬性的訪問層級.
還有其他幾個函數 用法一樣.
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
3.讀取屬性
建立了屬性,那麼該如何讀取此屬性呢?
zend_read_property(“,`< zval *object>`,`< char *name>`,`< int name_length>`,`< zend_bool silent TSRMLS_DC>`);
就要使用這個函數了,它將取得到的屬性訊息返回到一個zval結構體中
這時候要用到函數getThis();
這個函數會返回一個zval的指標.
因為是一個對像 所以儲存在結構體_zend_object_value 中
typedef struct _zend_object_value {
zend_object_handle handle;
zend_object_handlers *handlers;
} zend_object_value;
第一個參數會呼叫 zend_object_handler所指向的函數指標get_class_entry來取得現用的執行的類的訊息.
第一個參數應該是 Z_OBJEC_P(getThis());
第二個參數是 getThis();
它定義為 #define getThis() (this_ptr);
this_ptr是什麼東西我還不確定,我想應該是PHP內核維護的一個儲存類訊息的zval對像.回頭再好好研究研究.
第三個參數是要取得的屬性
第四個參數是屬性的長度.
修改之後的getproperty方法
1
2
3
4
5
6
PHP_METHOD(Person,getproperty){
zval* self=getThis();
zval* name;
name=zend_read_property(Z_OBJCE_P(self),self,ZEND_STRL("name"),0 TSRMLS_CC);
php_printf("%s",name->value.str.val);
}
4.設定屬性
該如何更新屬性的值呢?
同樣給我們提供了一個函數
zend_update_property(“,`< zval *object>`,`< char *name>`,`< int name_length>`,`< zval *value TSRMLS_DC>`)
前四個參數與zend_read_property相同.
不同的是最後一個zval*value.它是我們屬性的值..因為他是一個zval的指標,所以我們需要將通過zend_parse_parameters取得到的參數轉為一個zval的指標.
修改後的setproperty方法.
1
2
3
4
5
6
7
8
9
10
11
12
13
PHP_METHOD(Person,setproperty){
char *key=NULL;
int key_len;
char *val=NULL;
int val_len;
zval* self=getThis();
zval* value;
if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,"ss",&key,&key_len,&val,&val_len)==FAILURE){
return;
}
MAKE_STD_ZVAL(value);
ZVAL_STRINGL(value,val,val_len,1);
zend_update_property(Z_OBJCE_P(self),self,key,key_len,value TSRMLS_CC);
最後make && make install,重啟apache.
這樣我們在 php代碼裡.
1
2
3
4
5
<?php
$a=new Person();
$a->setproperty("name","this is siren");
$a->getproperty();
?>
就可以輸出我們通過setproperty設定的值了.
聲明:本文為斯人原創,全部為作者一一分析得之,有不對的地方望賜教。
歡迎轉載,轉載請註明出處 。
本文位址:http://imsiren.com/archives/581