詳解 php 反射機制原理

樹下水月發表於2020-05-05

一、介紹

 PHP5新增了一項新的功能:Reflection。這個功能使得phper可以reverse-engineer class, interface,function,method and extension。通過PHP程式碼,就可以得到某object的所有資訊,並且可以和它互動。
 反射是什麼?
它是指在PHP執行狀態中,擴充套件分析PHP程式,匯出或提取出關於類、方法、屬性、引數等的詳細資訊,包括註釋。這種動態獲取的資訊以及動態呼叫物件的方法的功能稱為反射API。反射是操縱物件導向範型中元模型的API,其功能十分強大,可幫助我們構建複雜,可擴充套件的應用。
其用途如:自動載入外掛,自動生成文件,甚至可用來擴充PHP語言。
php反射api由若干類組成,可幫助我們用來訪問程式的後設資料或者同相關的註釋互動。藉助反射我們可以獲取諸如類實現了那些方法,建立一個類的例項(不同於用new建立),呼叫一個方法(也不同於常規呼叫),傳遞引數,動態呼叫類的靜態方法。
      反射api是php內建的oop技術擴充套件,包括一些類,異常和介面,綜合使用他們可用來幫助我們分析其它類,介面,方法,屬性,方法和擴充套件。這些oop擴充套件被稱為反射。
      通過ReflectionClass,我們可以得到Person類的以下資訊:
     1)常量 Contants
     2)屬性 Property Names
     3)方法 Method Names靜態
     4)屬性 Static Properties
     5)名稱空間 Namespace
     6)Person類是否為final或者abstract
————————————————

 2、程式碼

  2.1  定義一個類   (類裡包含 成員變數、方法、註釋等)。

class Refl
{
    public $a = 1;
    private $ab = 2;
 
    public static $instance = null;
 
    /**
     * A類的abc 方法
     * @param $a
     * @param $b
     * @return string
     */
    public function abc($a, $b)
    {
        return $a . "|" . $b;
    }
 
    /**
     * type 方法
     * @param int $type
     * @return int
     */
    public function mf($type = 1)
    {
        return $type;
    }
 
    public function emp()
    {
        return 'emp';
    }
}

 

   2.2 測試用例 

 $obj = new \Refl();
        //dump($obj);
 
        $obj2 = new \ReflectionClass($obj); // 建立 A 類的反射類
        //dump($obj2);
 
        $instance = $obj2->newInstance(); // 相當於例項化了A 類
        //dump($instance);
 
        $methods = $obj2->getMethods(); // 獲取類中的所有方法
        //dump($methods);
 
        foreach ($methods as $method) {
           // dump($method->getDocComment()); // 獲取方法註釋
        }
 
        $properties = $obj2->getProperties(); // 獲取類中的所有屬性
        //dump($properties);
 
        // 方法1
        //echo $instance->abc(1, 2);
 
        // 方法2
        $method = $obj2->getMethod('abc');
        //echo $method->invokeArgs($instance, ["1111", 2222]);
 
        // 方法3
        $method = $obj2->getMethod('emp');
        //echo $method->invoke($instance);
 
        // 判斷某個方法是否是私有的
        $method = new \ReflectionMethod($obj, "abc");
        if ($method->isPublic()) {
            //echo "此方法是公有的";
        }
 
        $params = $method->getParameters();
        //dump($params); // 獲取方法中的引數
 
        $number = $method->getNumberOfParameters(); // 獲取引數的個數
        //dump($number);

 

相關文章