聲明:本文為斯人原創,全部為作者一一分析得之,有不對的地方望賜教。
歡迎轉載,轉載請注明出處 。
本文位址:http://imsiren.com/archives/581
類建立好了..
那麼類肯定不止這些東西,它由繼承,屬性,傳回值等.
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代碼如下
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:屬性的通路級别.
還有其他幾個函數 用法一樣.
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();
第三個參數是要擷取的屬性
第四個參數是屬性的長度.
修改之後的getproperty方法
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方法.
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代碼裡.
<?php
$a=new Person();
$a->setproperty("name","this is siren");
$a->getproperty();
?>
就可以輸出我們通過setproperty設定的值了.
原文出處: http://imsiren.com/archives/581