首頁 後端開發 php教程 php反射API 簡單教程

php反射API 簡單教程

Jul 01, 2017 am 10:40 AM
api php 教學

說起反射ApI,自我感覺PHP中的反射ApI和java中的java.lang.reflect套件差不多,都是由可以列印和分析類別成員屬性、方法的一組內建類別組成的。可能你已經學過物件函數例如:get_class_vars()但是使用反射API會更加的靈活、輸出資訊會更加詳細。

  首先我們需要知道,反射API不僅僅是用來檢查類別的,它本身包括一組類,用來完成各種功能:常用的類別如下:

Reflection類別 #可以列印類別的基本訊息,(透過提供的靜態export()函數)
ReflectionMethod類別 #見名知意,列印類別方法、得到方法的具體資訊等
ReflectionClass類別 用於得到類別訊息,例如得到類別包含的方法,類別本的屬性,是不是抽象類等
ReflectionParameter類別 #顯示參數的訊息,可以動態得到已知方法的傳參情況
ReflectionException類別 # 用於顯示錯誤訊息
ReflectionExtension類別 得到PHP的擴充訊息,可以判斷擴充是否存在等
#

 

 







傳統的列印類別資訊與反射APi的差異

下面是一段我自己寫的參數程序,用於演示反射的使用:

<?php

class Person
{
    //成员属性
    public $name;
    public $age; 

    //构造方法
    public function construct($name, $age)
    {
        $this->name = $name;
        $this->age = $age;
    }

    //成员方法
    public function set_name($name)
    {
        $this->$name = $name;
    }

    public function get_name()
    {
        return $this->$name;
    }

    public function get_age()
    {
        return $this->$age;
    }

    public function get_user_info()
    {
        $info = &#39;姓名:&#39; . $this->name;
        $info .= &#39; 年龄:&#39; . $this->age;
        return $info;
    }
}

class Teacher extends Person
{
    private $salary = 0;

    public function construct($name, $age, $salary)
    {
        parent::construct($name, $age);
        $this->salary = $salary;
    }

    public function get_salary()
    {
        return $this->$salary;
    }

    public function get_user_info()
    {
        $info = parent::get_user_info();
        $info .= " 工资:" . $this->salary;
        return $info;
    }
}

class Student extends Person
{
    private $score = 0;

    public function construct($name, $age, $score)
    {
        parent::construct($name, $age);
        $this->score = $score;
    }

    public function get_score()
    {
        return $this->score;        
    }

    public function get_user_info()
    {
        $info = parent::get_user_info();
        $info .= " 成绩:" . $this->score;
        return $info;
    }
}

header("Content-type:text/html;charset=utf8;");
$te_obj = new Teacher(&#39;李老师&#39;, &#39;36&#39;, &#39;2000&#39;);
$te_info = $te_obj->get_user_info();

$st_obj = new Student(&#39;小明&#39;, &#39;13&#39;, &#39;80&#39;);
$st_info = $st_obj->get_user_info();
登入後複製

我們先用var_dump();打印類別的信息,如下所示,可以看出只是打印出類的簡單訊息,甚至連方法也沒有,所以從這樣的訊息中看不出其他游泳的訊息。

var_dump(

$te_obj);

object(Teacher)#1 (3) {
      ["salary":"Teacher":private]=>
          string(4) "2000"
      ["name"]=>
          string(9) "李老师"
      ["age"]=>
          string(2) "36"
}
登入後複製

  Reflection::export($obj);

#  我們利用Reflection提供的內建方法export來列印訊息,如下所示:

  列印出的資訊比較完整,包括成員屬性,成員方法,類別的基本訊息,檔案路徑,方法訊息,方法屬性,傳參情況,所在檔案的行數等等。比較全面的展示了類的資訊。可以看出var_dump()或print_r只能顯示類的簡要信息,好多信息根本顯示不出來,所以他們只能做簡單的調試之用,反射Api則提供的類更多的信息,可以很好地幫助我們知道呼叫類別的情況,這對寫接口,特別是呼叫別人的接口提供了極大的便利。如果出了問題,也可以幫忙調試。

object(Teacher)#1 (3) {
      ["salary":"Teacher":private]=>
          string(4) "2000"
      ["name"]=>
          string(9) "李老师"
      ["age"]=>
          string(2) "36"
}
Class [  class Person ] {
      @@ /usr/local/www/phptest/oop/reflaction.php 3-38
      - Constants [0] {
      }
      - Static properties [0] {
      }
      - Static methods [0] {
 }
  - Properties [2] {
        Property [  public $name ]
        Property [  public $age ]
  }

  - Methods [5] {
    Method [  public method construct ] {
      @@ /usr/local/www/phptest/oop/reflaction.php 10 - 14

      - Parameters [2] {
        Parameter #0 [  $name ]

.....
登入後複製

反射API的具體使用:#  看過框架原始碼的同學都知道框架都可以載入第三方的插件、類別庫等等。下面這個例子咱們借助反射APi簡單實現這個功能,該例子原型是我從書上學習的,我理解後按照自己的思路寫了一套:要實現的功能:用一個類去動態的遍歷調用Property類對象,類別可以自由的載入其他的類別的方法,而不用吧類別嵌入到已有的程式碼,也不用手動去呼叫類別庫的程式碼。     約定:每個類別要包含work方法,可以抽象化一個介面。可以把每個類別的資訊放在檔案中,相當於各個類別庫訊息,透過類別保存的Property類別庫的對應對象,然後呼叫每個類別庫的work方法。

  以下是基礎程式碼:

###
/*属性接口*/
interface Property
{
    function work();
}

class Person
{
    public $name;
    public function construct($name)
    {
        $this->name = $name;
    }
}

class StudentController implements Property
{
    //set方法,但需要Person对象参数
    public function setPerson(Person $obj_person)
    {
        echo &#39;Student &#39; . $obj_person->name;
    }

    //work方法简单实现
    public function work()
    {
        echo &#39;student working!&#39;;
    }
}

class EngineController implements Property
{
    //set方法
    public function setWeight($weight)
    {
        echo &#39;this is engine -> set weight&#39;;
    }

    public function setPrice($price)
    {
        echo "this is engine -> set price";
    }

    //work方法简单实现
    public function work()
    {
        echo &#39;engine working!&#39;;
    }
}
登入後複製
#######    這裡定義了兩個相似類別實作Property接口,同時都簡單實作work()方法StudentController類別稍微不同,參數需要Person對象,同時我們可以使用檔案來保存各個類別的訊息,我們也可以用成員屬性來代替。 ######
class Run
{
    public static $mod_arr = [];
    public static $config = [
        &#39;StudentController&#39; => [
            &#39;person&#39; => &#39;xiao ming&#39;
        ],
        &#39;EngineController&#39;  => [
            &#39;weight&#39; => &#39;500kg&#39;,
            &#39;price&#39;  => &#39;4000&#39;
        ]
    ];

    //加载初始化
    public function construct()
    {
        $config = self::$config;
        //用于检查是不是实现类
        $property = new ReflectionClass(&#39;Property&#39;);
        foreach ($config as $class_name => $params) {
            $class_reflect = new ReflectionClass($class_name);
            if(!$class_reflect->isSubclassOf($property)) {//用isSubclassOf方法检查是否是这个对象
                echo &#39;this is  error&#39;;
                continue;
            }

            //得到类的信息
            $class_obj = $class_reflect->newInstance();
            $class_method = $class_reflect->getMethods();

            foreach ($class_method as $method_name) {
                $this->handle_method($class_obj, $method_name, $params);
            }
            array_push(self::$mod_arr, $class_obj);
        }
    }

    //处理方法调用
    public function handle_method(Property $class_obj, ReflectionMethod $method_name, $params)
    {
        $m_name = $method_name->getName();
        $args = $method_name->getParameters();

        if(count($args) != 1 || substr($m_name, 0, 3) != &#39;set&#39;) {    
            return false;
        }
        //大小写转换,做容错处理
        $property = strtolower(substr($m_name, 3));
     
        if(!isset($params[$property])) {
            return false;
        }

        $args_class = $args[0]->getClass();
        echo &#39;<pre class="brush:php;toolbar:false">&#39;;
        if(empty($args_class)) {
            $method_name->invoke($class_obj, $params[$property]); //如果得到的类为空证明需要传递基础类型参数
        } else {
            $method_name->invoke($class_obj, $args_class->newInstance($params[$property])); //如果不为空说明需要传递真实对象
        }
    }
}

//程序开始
new Run();
登入後複製
######  到此程式結束,Run啟動會自動呼叫建構方法,初始化要載入類別庫的其他成員屬性,包括初始化和執行對應方法操作,這裡只是完成了對應的set方法。其中###$mod_arr屬性保存了所有呼叫類別的對象,每個對象包含數據,可以遍歷包含的對象來以此呼叫work()方法。 ###############  程式只做輔助理解反射PAI用,各個功能沒有完善,裡面用到了很多反射API的類,方法,下面會有各個方法的總結。 ##################反射API###提供的常用類別和函數:###############下面提供的函數是常用的函數,不是全部,有的函數根本用不到,所以我們有往撒謊那個寫,想看全部的可以到網上搜一下,比較多。提供的這組方法沒有必要背下來,用到的時候可以查看。 ######
1:Reflection
  public static export(Reflector r [,bool return])//打印类或方法的详细信息
  public static  getModifierNames(int modifiers)  //取得修饰符的名字

2:ReflectionMethod:
    public static string export()                       //打印该方法的信息
    public mixed invoke(stdclass object, mixed* args)   //调用对应的方法
    public mixed invokeArgs(stdclass object, array args)//调用对应的方法,传多参数
    public bool isFinal()        //方法是否为final
    public bool isAbstract()     //方法是否为abstract
    public bool isPublic()       //方法是否为public
    public bool isPrivate()      //方法是否为private
    public bool isProtected()    //方法是否为protected
    public bool isStatic()       //方法是否为static
    public bool isConstructor()  //方法是否为构造函数

3:ReflectionClass:
    public static string export()  //打印类的详细信息
    public string getName()        //取得类名或接口名
    public bool isInternal()       //类是否为系统内部类
    public bool isUserDefined()    //类是否为用户自定义类
    public bool isInstantiable()   //类是否被实例化过
    public bool hasMethod(string name)  //类是否有特定的方法
    public bool hasProperty(string name)//类是否有特定的属性
    public string getFileName()         //获取定义该类的文件名,包括路径名
    public int getStartLine()           //获取定义该类的开始行
    public int getEndLine()             //获取定义该类的结束行
    public string getDocComment()       //获取该类的注释
    public ReflectionMethod getConstructor()           //取得该类的构造函数信息
    public ReflectionMethod getMethod(string name)     //取得该类的某个特定的方法信息
    public ReflectionMethod[] getMethods()             //取得该类的所有的方法信息
    public ReflectionProperty getProperty(string name) //取得某个特定的属性信息
    public ReflectionProperty[] getProperties()        //取得该类的所有属性信息
    public array getConstants()                        //取得该类所有常量信息
    public mixed getConstant(string name)              //取得该类特定常量信息
    public ReflectionClass[] getInterfaces()           //取得接口类信息
    public bool isInterface()  //测试该类是否为接口
    public bool isAbstract()   //测试该类是否为抽象类

4:ReflectionParameter:
    public static string export()     //导出该参数的详细信息
    public string getName()           //取得参数名
    public bool isPassedByReference() //测试该参数是否通过引用传递参数
    public ReflectionClass getClass() //若该参数为对象,返回该对象的类名
    public bool isArray()             //测试该参数是否为数组类型
    public bool allowsNull()          //测试该参数是否允许为空
    public bool isOptional()          //测试该参数是否为可选的,当有默认参数时可选
    public bool isDefaultValueAvailable() //测试该参数是否为默认参数
    public mixed getDefaultValue()        //取得该参数的默认值

5:ReflectionExtension类
    public static  export()    //导出该扩展的所有信息
    public string getName()    //取得该扩展的名字
    public string getVersion() //取得该扩展的版本
    public ReflectionFunction[] getFunctions()   //取得该扩展的所有函数
    public array getConstants()  //取得该扩展的所有常量
    public array getINIEntries() //取得与该扩展相关的,在php.ini中的指令信息
}
登入後複製

以上是php反射API 簡單教程的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

適用於 Ubuntu 和 Debian 的 PHP 8.4 安裝和升級指南 適用於 Ubuntu 和 Debian 的 PHP 8.4 安裝和升級指南 Dec 24, 2024 pm 04:42 PM

PHP 8.4 帶來了多項新功能、安全性改進和效能改進,同時棄用和刪除了大量功能。 本指南介紹如何在 Ubuntu、Debian 或其衍生版本上安裝 PHP 8.4 或升級到 PHP 8.4

我後悔之前不知道的 7 個 PHP 函數 我後悔之前不知道的 7 個 PHP 函數 Nov 13, 2024 am 09:42 AM

如果您是經驗豐富的PHP 開發人員,您可能會感覺您已經在那裡並且已經完成了。操作

如何設定 Visual Studio Code (VS Code) 進行 PHP 開發 如何設定 Visual Studio Code (VS Code) 進行 PHP 開發 Dec 20, 2024 am 11:31 AM

Visual Studio Code,也稱為 VS Code,是一個免費的原始碼編輯器 - 或整合開發環境 (IDE) - 可用於所有主要作業系統。 VS Code 擁有大量針對多種程式語言的擴展,可以輕鬆編寫

在PHP API中說明JSON Web令牌(JWT)及其用例。 在PHP API中說明JSON Web令牌(JWT)及其用例。 Apr 05, 2025 am 12:04 AM

JWT是一種基於JSON的開放標準,用於在各方之間安全地傳輸信息,主要用於身份驗證和信息交換。 1.JWT由Header、Payload和Signature三部分組成。 2.JWT的工作原理包括生成JWT、驗證JWT和解析Payload三個步驟。 3.在PHP中使用JWT進行身份驗證時,可以生成和驗證JWT,並在高級用法中包含用戶角色和權限信息。 4.常見錯誤包括簽名驗證失敗、令牌過期和Payload過大,調試技巧包括使用調試工具和日誌記錄。 5.性能優化和最佳實踐包括使用合適的簽名算法、合理設置有效期、

php程序在字符串中計數元音 php程序在字符串中計數元音 Feb 07, 2025 pm 12:12 PM

字符串是由字符組成的序列,包括字母、數字和符號。本教程將學習如何使用不同的方法在PHP中計算給定字符串中元音的數量。英語中的元音是a、e、i、o、u,它們可以是大寫或小寫。 什麼是元音? 元音是代表特定語音的字母字符。英語中共有五個元音,包括大寫和小寫: a, e, i, o, u 示例 1 輸入:字符串 = "Tutorialspoint" 輸出:6 解釋 字符串 "Tutorialspoint" 中的元音是 u、o、i、a、o、i。總共有 6 個元

您如何在PHP中解析和處理HTML/XML? 您如何在PHP中解析和處理HTML/XML? Feb 07, 2025 am 11:57 AM

本教程演示瞭如何使用PHP有效地處理XML文檔。 XML(可擴展的標記語言)是一種用於人類可讀性和機器解析的多功能文本標記語言。它通常用於數據存儲

解釋PHP中的晚期靜態綁定(靜態::)。 解釋PHP中的晚期靜態綁定(靜態::)。 Apr 03, 2025 am 12:04 AM

靜態綁定(static::)在PHP中實現晚期靜態綁定(LSB),允許在靜態上下文中引用調用類而非定義類。 1)解析過程在運行時進行,2)在繼承關係中向上查找調用類,3)可能帶來性能開銷。

什麼是PHP魔術方法(__ -construct,__destruct,__call,__get,__ set等)並提供用例? 什麼是PHP魔術方法(__ -construct,__destruct,__call,__get,__ set等)並提供用例? Apr 03, 2025 am 12:03 AM

PHP的魔法方法有哪些? PHP的魔法方法包括:1.\_\_construct,用於初始化對象;2.\_\_destruct,用於清理資源;3.\_\_call,處理不存在的方法調用;4.\_\_get,實現動態屬性訪問;5.\_\_set,實現動態屬性設置。這些方法在特定情況下自動調用,提升代碼的靈活性和效率。

See all articles