1. 程式人生 > >php高階特性-反射

php高階特性-反射

一、什麼是反射?

它是指在PHP執行狀態中,擴充套件分析PHP程式,匯出或提取出關於類、方法、屬性、引數等的詳細資訊,包括註釋。這種動態獲取的資訊以及動態呼叫物件的方法的功能稱為反射API。
反射是操縱面向物件範型中元模型的API,其功能十分強大,可幫助我們構建複雜,可擴充套件的應用。

二、反射的用途

三、反射具體應用例項-以CI框架的一個實現例子來說

反射功能很強大,那具體怎麼用呢?有哪些應用場景呢?以CI框架的CI_Upload類來說明。(全域性搜尋ReflectionClass了也就只發現了這一處有用到反射。)

這個方法的核心邏輯是呼叫方例項化CI_Upload

時傳一個$config陣列,方法內將數組裡的所有配置賦值給相應的類成員屬性(如果屬性有對應的set_*方法則呼叫set_*方法)

方法一、不使用反射的寫法:

public function initialize(array $config = array(), $reset = TRUE)
{
    $reflection = new ReflectionClass($this);
...
    #遍歷config,如果存在set_方法呼叫set方法,沒有則直接賦值
    foreach ($config as $key => $v) {
        if (method_exists($this
, 'set_' . $key)) { $this->{'set_' . $key}($v); }else{ $this->$key =$v; } } ...

這種方法有個弊端:無法判斷config陣列的所有key是否合法,是否是類的成員屬性
而使用反射則可以實現判斷。
反射在這裡的體現的好處是:可以判斷類是否存在屬性(hasProperty),和判斷類是否存在方法(hasMethod)。

方法二、CI框架內的實現

D:\project\app\system\libraries\Upload.php

/**
 * Initialize preferences
 *
 * @param
array $config * @param bool $reset * @return CI_Upload */
public function initialize(array $config = array(), $reset = TRUE) { $reflection = new ReflectionClass($this); ... foreach ($config as $key => &$value) { if ($key[0] !== '_' && $reflection->hasProperty($key)) { if ($reflection->hasMethod('set_'.$key)) { $this->{'set_'.$key}($value); } else { $this->$key = $value; } } } ...

四、總結

關於反射(不管是反射類(ReflectionClass)還是反射函式ReflectionFunction,實際就是類和函式的區別)記住一點就行:反射類/函式可以獲取類的一切資訊,包括:
- 類基本資訊(類名、是否是抽象類、是否可例項化、類是否為final或者abstract)
- 類的方法、方法是否存在、方法返回值、方法的註釋、Method Names
- 類的屬性,靜態屬性,常量
- 所在名稱空間 Namespace

針對有以上情況需求的,不妨利用反射來解決:)

參考資料