php高階特性-反射
阿新 • • 發佈:2019-01-10
一、什麼是反射?
它是指在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
針對有以上情況需求的,不妨利用反射來解決:)