# 11.2 PHP中的面向對象(二)
在上一節里我們已經看了下如何操作一個對象的方法,這一節主要描述與對象屬性有關的東西。有關如何對它進行定義的操作我們已經在上一章中描述過了,這里不再敘述,只講對其的操作。
## 讀取對象的屬性
````c
ZEND_API zval *zend_read_property(zend_class_entry *scope, zval *object, char *name, int name_length, zend_bool silent TSRMLS_DC);
ZEND_API zval *zend_read_static_property(zend_class_entry *scope, char *name, int name_length, zend_bool silent TSRMLS_DC);
````
zend_read_property函數用于讀取對象的屬性,而zend_read_static_property則用于讀取靜態屬性。可以看出,靜態屬性是直接保存在類上的,與具體的對象無關。
silent參數:
<ul>
<li>0: 如果屬性不存在,則拋出一個notice錯誤。</li>
<li>1: 如果屬性不存在,不報錯。</li>
</ul>
如果所查的屬性不存在,那么此函數將返回IS_NULL類型的zval。
### 更新對象的屬性
````c
ZEND_API void zend_update_property(zend_class_entry *scope, zval *object, char *name, int name_length, zval *value TSRMLS_DC);
ZEND_API int zend_update_static_property(zend_class_entry *scope, char *name, int name_length, zval *value TSRMLS_DC);
````
zend_update_property用來更新對象的屬性,zend_update_static_property用來更新類的靜態屬性。如果對象或者類中沒有相關的屬性,函數將自動的添加上。
### 讀寫對象與類屬性的實例
假設我們已經在擴展中定義好下面的類:
````php
class baby
{
public $age;
public static $area;
public function __construct($age, $area)
{
$this->age = $age;
self::$area = $area;
var_dump($this->age, self::$area);
}
}
ZEND_METHOD(baby, __construct)
{
zval *age, *area;
zend_class_entry *ce;
ce = Z_OBJCE_P(getThis());
if( zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &age, &area) == FAILURE )
{
printf("Error\n");
RETURN_NULL();
}
zend_update_property(ce, getThis(), "age", sizeof("age")-1, age TSRMLS_CC);
zend_update_static_property(ce, "area", sizeof("area")-1, area TSRMLS_CC);
age = NULL;
area = NULL;
age = zend_read_property(ce, getThis(), "age", sizeof("age")-1, 0 TSRMLS_DC);
php_var_dump(&age, 1 TSRMLS_CC);
area = zend_read_static_property(ce, "area", sizeof("area")-1, 0 TSRMLS_DC);
php_var_dump(&area, 1 TSRMLS_CC);
}
//為類添加age 和 area屬性
PHP_MINIT_FUNCTION(say_hello)
{
zend_class_entry ce;
INIT_CLASS_ENTRY(ce,"baby",myclass_method);
baby_ce = zend_register_internal_class(&ce TSRMLS_CC);
zend_declare_property_null(baby_ce, "age", strlen("age"), ZEND_ACC_PUBLIC TSRMLS_CC);
zend_declare_property_null(baby_ce, "area", strlen("area"), ZEND_ACC_STATIC|ZEND_ACC_PUBLIC TSRMLS_CC);
return SUCCESS;
}
````
<div class="tip-common">
感謝 [@看你取的破名](http://weibo.com/taokuizu) 發現的錯誤。
</div>
### 一些其它的快捷函數
#### 更新對象與類的屬性
````c
ZEND_API void zend_update_property_null(zend_class_entry *scope, zval *object, char *name, int name_length TSRMLS_DC);
ZEND_API void zend_update_property_bool(zend_class_entry *scope, zval *object, char *name, int name_length, long value TSRMLS_DC);
ZEND_API void zend_update_property_long(zend_class_entry *scope, zval *object, char *name, int name_length, long value TSRMLS_DC);
ZEND_API void zend_update_property_double(zend_class_entry *scope, zval *object, char *name, int name_length, double value TSRMLS_DC);
ZEND_API void zend_update_property_string(zend_class_entry *scope, zval *object, char *name, int name_length, const char *value TSRMLS_DC);
ZEND_API void zend_update_property_stringl(zend_class_entry *scope, zval *object, char *name, int name_length, const char *value, int value_length TSRMLS_DC);
ZEND_API int zend_update_static_property_null(zend_class_entry *scope, char *name, int name_length TSRMLS_DC);
ZEND_API int zend_update_static_property_bool(zend_class_entry *scope, char *name, int name_length, long value TSRMLS_DC);
ZEND_API int zend_update_static_property_long(zend_class_entry *scope, char *name, int name_length, long value TSRMLS_DC);
ZEND_API int zend_update_static_property_double(zend_class_entry *scope, char *name, int name_length, double value TSRMLS_DC);
ZEND_API int zend_update_static_property_string(zend_class_entry *scope, char *name, int name_length, const char *value TSRMLS_DC);
ZEND_API int zend_update_static_property_stringl(zend_class_entry *scope, char *name, int name_length, const char *value, int value_length TSRMLS_DC);
````
## links
* 11.1 [生成對象的實例](<11.1.md>)
* 11.3 [小結](<11.3.md>)
- about
- 開始閱讀
- 目錄
- 1 PHP的生命周期
- 1.讓我們從SAPI開始
- 2.PHP的啟動與終止
- 3.PHP的生命周期
- 4.線程安全
- 5.小結
- 2 PHP變量在內核中的實現
- 1. 變量的類型
- 2. 變量的值
- 3. 創建PHP變量
- 4. 變量的存儲方式
- 5. 變量的檢索
- 6. 類型轉換
- 7. 小結
- 3 內存管理
- 1. 內存管理
- 2. 引用計數
- 3. 總結
- 4 動手編譯PHP
- 1. 編譯前的準備
- 2. PHP編譯前的config配置
- 3. Unix/Linux平臺下的編譯
- 4. 在Win32平臺上編譯PHP
- 5. 小結
- 5 Your First Extension
- 1. 一個擴展的基本結構
- 2. 編譯我們的擴展
- 3. 靜態編譯
- 4. 編寫函數
- 5. 小結
- 6 函數返回值
- 1. 一個特殊的參數:return_value
- 2. 引用與函數的執行結果
- 3. 小結
- 7 函數的參數
- 1. zend_parse_parameters
- 2. Arg Info 與類型綁定
- 3. 小結
- 8 使用HashTable與{數組}
- 1. 數組(C中的)與鏈表
- 2. 操作HashTable的API
- 3. 在內核中操作PHP語言中數組
- 4. 小結
- 9 PHP中的資源類型
- 1. 復合類型的數據——{資源}
- 2. Persistent Resources
- 3. {資源}自有的引用計數
- 4. 小結
- 10 PHP中的面向對象(一)
- 1. zend_class_entry
- 2. 定義一個類
- 3. 定義一個接口
- 4. 類的繼承與接口的實現
- 5. 小結
- 11 PHP中的面向對象(二)
- 1. 生成對象的實例與調用方法
- 2. 讀寫對象的屬性
- 3. 小結
- 12 啟動與終止的那點事
- 2. 小結
- 1. 關于生命周期
- 2. MINFO與phpinfo
- 3. 常量
- 4. PHP擴展中的全局變量
- 5. PHP語言中的超級全局變量
- 6. 小結
- 13 INI設置
- 1. 聲明和訪問ini設置
- 2. 小結
- 2. 小結
- 14 流式訪問
- 1. 概覽
- 2. 打開流
- 3. 訪問流
- 4. 靜態資源操作
- 5. 小結
- 15 流的實現
- 1. php流的表象之下
- 2. 包裝器操作
- 3. 實現一個包裝器
- 4. 操縱
- 5. 檢查
- 6. 小結
- 16 有趣的流
- 1. 上下文
- 2. 過濾器
- 3. 小結
- 17 配置和鏈接
- 1. autoconf
- 2. 庫的查找
- 3. 強制模塊依賴
- 4. Windows方言
- 5. 小結
- 18 擴展生成
- 1. ext_skel
- 2. PECL_Gen
- 3. 小結
- 19 設置宿主環境
- 1. 嵌入式SAPI
- 2. 構建并編譯一個宿主應用
- 3. 通過嵌入包裝重新創建cli
- 4. 老技術新用
- 5. 小結
- 20 高級嵌入式
- 1. 回調到php中
- 2. 錯誤處理
- 3. 初始化php
- 4. 覆寫INI_SYSTEM和INI_PERDIR選項
- 5. 捕獲輸出
- 6. 同時擴展和嵌入
- 7. 小結
- 約定