簡介
PHP Reflection API是PHP5纔有的新功能,它是用來導出或提取出關於類、方法、屬性、參數等的詳細信息,包括註釋。
用得比較多的就只有兩個ReflectionClass與ReflectionObject,兩個的用法都一樣,只是前者針對類,後者針對對象,後者是繼承前者的類;然後其中又有一些屬性或方法能返回對應的Reflection對象
反射是什麼?
它是指在PHP運行狀態中,擴展分析PHP程序,導出或提取出關於類、方法、屬性、參數等的詳細信息,包括註釋。這種動態獲取的信息以及動態調用對象的方法的功能稱爲反射API。反射是操縱面向對象範型中元模型的API,其功能十分強大,可幫助我們構建複雜,可擴展的應用。
其用途如:自動加載插件,自動生成文檔,甚至可用來擴充PHP語言。
PHP反射api由若干類組成,可幫助我們用來訪問程序的元數據或者同相關的註釋交互。藉助反射我們可以獲取諸如類實現了那些方法,創建一個類的實例(不同於用new創建),調用一個方法(也不同於常規調用),傳遞參數,動態調用類的靜態方法。
反射api是PHP內建的OOP技術擴展,包括一些類,異常和接口,綜合使用他們可用來幫助我們分析其它類,接口,方法,屬性,方法和擴展。這些OOP擴展被稱爲反射。
ReflectionClass
具體參考手冊:http://php.net/manual/zh/class.reflectionclass.php
一、通過ReflectionClass,我們可以得到Person類的以下信息:
1.常量 Contants
2.屬性 Property Names
3.方法 Method Names靜態
4.屬性 Static Properties
5.命名空間 Namespace
6.Person類是否爲final或者abstract
7.Person類是否有某個方法
接下來反射它,只要把類名"Person"傳遞給ReflectionClass就可以了:
$class = new ReflectionClass('Person'); // 建立 Person這個類的反射類
$instance = $class->newInstanceArgs($args); // 相當於實例化Person 類
1)獲取屬性(Properties):
代碼如下:
$properties = $class->getProperties();
foreach ($properties as $property) {
echo $property->getName() . "\n";
}
// 輸出:
// _allowDynamicAttributes
// id
// name
// biography
默認情況下,ReflectionClass會獲取到所有的屬性,private 和 protected的也可以。如果只想獲取到private屬性,就要額外傳個參數:
代碼如下:
$private_properties = $class->getProperties(ReflectionProperty::IS_PRIVATE);
可用參數列表:
代碼如下:
ReflectionProperty::IS_STATIC
ReflectionProperty::IS_PUBLIC
ReflectionProperty::IS_PROTECTED
ReflectionProperty::IS_PRIVATE
通過$property->getName()可以得到屬性名。2)獲取註釋:
通過getDocComment可以得到寫給property的註釋。
代碼如下:
foreach ($properties as $property) {
if ($property->isProtected()) {
$docblock = $property->getDocComment();
preg_match('/ type\=([a-z_]*) /', $property->getDocComment(), $matches);
echo $matches[1] . "\n";
}
}
// Output:
// primary_autoincrement
// varchar
// text
3)獲取類的方法
代碼如下:
getMethods() 來獲取到類的所有methods。
hasMethod(string) 是否存在某個方法
getMethod(string) 獲取方法
4)執行類的方法:
代碼如下:
$instance->getName(); // 執行Person 裏的方法getName
// 或者:
$method = $class->getmethod('getName'); // 獲取Person 類中的getName方法
$method->invoke($instance); // 執行getName 方法
// 或者:
$method = $class->getmethod('setName'); // 獲取Person 類中的setName方法
$method->invokeArgs($instance, array('snsgou.com'));
二、通過ReflectionMethod,我們可以得到Person類的某個方法的信息:
1.是否“public”、“protected”、“private” 、“static”類型
2.方法的參數列表
3.方法的參數個數
4.反調用類的方法
代碼如下:
// 執行detail方法
$method = new ReflectionMethod('Person', 'test');
if ($method->isPublic() && !$method->isStatic()) {
echo 'Action is right';
}
echo $method->getNumberOfParameters(); // 參數個數
echo $method->getParameters(); // 參數對象數組
舉例說明:
- <?php
- class ClassName{
- /**
- * [$a description]公開變量
- * @var integer
- */
- public $a=1;
- //私有
- private $b=2;
- protected $c=3;
- const D=4;
- const E=5;
- public function __construct($value,$key)
- {
- }
- public function a(){
- echo "a";
- }
- private function b(){
- echo "b";
- }
- protected function c(){
- echo "c";
- }
- public function p($key,$value){
- echo $key;
- echo $value;
- }
- }
- $class=new ClassName(1,2);
- $obj=new ReflectionClass($class);
- //取出類裏面定義的常量
- print_r($obj->getConstant ('D'));
- //取出所有常量
- print_r($obj->getConstants ());
- //方法很多,就不一一使用了,挑幾個感覺比較常用的用用~~
- //檢測方法是否已經存在
- var_dump($obj->hasMethod('a'));//方法存在,返回true
- var_dump($obj->hasMethod('nnn'));//方法不存在,返回false
- //實例化一個類(函數裏面的值回傳到構造函數裏面)
- $obj->newInstance(3,4)->a();//輸出a,$obj->newInstance(3,4)執行完畢之後返回的是ClassName類
- //取出類的方法並使用這個方法,這個函數返回的是ReflectionMethod對象了
- $method=$obj->getMethod('a');
- //使用ReflectionMethod方法就是執行這個方法,函數裏面的值一個對象示例
- $method->invoke($class);
- //傳參
- $method=$obj->getMethod('p');
- //參數直接安裝順序直接寫在對象後面
- $method->invoke($class,1,2);
- //或者用invokeArgs方法,用數組傳參數,在數組裏面按順序放好就ok了
- $method->invokeArgs($class, array('zzz','aaa'));
- //判斷方法屬性
- var_dump($method->isPublic());//true
- var_dump($method->isProtected());//false
- ?>