什么是PHP反射API-創(chuàng)新互聯(lián)

本篇文章給大家分享的是有關(guān)什么是PHP反射API,小編覺得挺實用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

創(chuàng)新互聯(lián)專注于白水網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗。 熱誠為您提供白水營銷型網(wǎng)站建設(shè),白水網(wǎng)站制作、白水網(wǎng)頁設(shè)計、白水網(wǎng)站官網(wǎng)定制、微信小程序開發(fā)服務(wù),打造白水網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供白水網(wǎng)站排名全網(wǎng)營銷落地服務(wù)。

PHP中的反射API就像Java中的java.lang.reflect包一樣。它由一系列可以分析屬性、方法和類的內(nèi)置類組成。它在某些方面和對象函數(shù)相似,比如get_class_vars(),但是更加靈活,而且可以提供更多信息。

反射API也可與PHP最新的面向?qū)ο筇匦砸黄鸸ぷ?,如訪問控制、接口和抽象類。舊的類函數(shù)則不太容易與這些新特性一起使用??催^框架源碼的朋友應(yīng)該對PHP的反射機制有一定的了解,像是依賴注入,對象池,類加載,一些設(shè)計模式等等,都用到了反射機制。

反射API的部分類

使用反射API這些類,可以獲得在運行時訪問對象、函數(shù)和腳本中的擴展的信息。通過這些信息可以用來分析類或者構(gòu)建框架。

描         述
Reflection為類的摘要信息提供靜態(tài)函數(shù)export()
ReflectionClass類信息和工具
ReflectionMethod類方法信息和工具
ReflectionParameter方法參數(shù)信息
ReflectionProperty類屬性信息
ReflectionFunction函數(shù)信息和工具
ReflectionExtensionPHP擴展信息
ReflectionException錯誤類

獲取類的信息

我們在工作中使用過一些用于檢查類屬性的函數(shù),例如:get_class_methods、getProduct等。這些方法對獲取詳細(xì)類信息有很大的局限性。

我們可以通過反射API類:Reflection 和 ReflectionClass 提供的靜態(tài)方法 export 來獲取類的相關(guān)信息, export 可以提供類的幾乎所有的信息,包括屬性和方法的訪問控制狀態(tài)、每個方法需要的參數(shù)以及每個方法在腳本文檔中的位置。這兩個工具類, export 靜態(tài)方法輸出結(jié)果是一致的,只是使用方式不同。

首先,構(gòu)建一個簡單的類

<?php

class Student {
    public    $name;
    protected $age;
    private   $sex;

    public function __construct($name, $age, $sex)
    {
        $this->setName($name);
        $this->setAge($age);
        $this->setSex($sex);
    }

    public function setName($name)
    {
       $this->name = $name;
    }

    protected function setAge($age)
    {
        $this->age = $age;
    }

    private function setSex($sex)
    {
        $this->sex = $sex;
    }
}

使用 ReflectionClass::export() 獲取類信息

ReflectionClass::export('Student');

打印結(jié)果:

Class [ class Student ] {
    @@ D:\wamp\www\test2.php 3-29
    - Constants [0] { }
    - Static properties [0] { }
    - Static methods [0] { }
    - Properties [3] {
        Property [ public $name ]
        Property [ protected $age ]
        Property [ private $sex ]
    }
    - Methods [4] {
        Method [ public method __construct ] {
            @@ D:\wamp\www\test2.php 8 - 13
            - Parameters [3] {
                Parameter #0 [ $name ]
                Parameter #1 [ $age ]
                Parameter #2 [ $sex ]
            }
        }
        Method [ public method setName ] {
            @@ D:\wamp\www\test2.php 15 - 18
            - Parameters [1] {
                Parameter #0 [ $name ]
            }
        }
        Method [ protected method setAge ] {
            @@ D:\wamp\www\test2.php 20 - 23
            - Parameters [1] {
                Parameter #0 [ $age ]
            }
        }
        Method [ private method setSex ] {
            @@ D:\wamp\www\test2.php 25 - 28
            - Parameters [1] {
                Parameter #0 [ $sex ]
            }
        }
    }
}

ReflectionClass類提供了非常多的工具方法,官方手冊給的列表如下:

ReflectionClass::__construct — 初始化 ReflectionClass 類
ReflectionClass::export — 導(dǎo)出一個類
ReflectionClass::getConstant — 獲取定義過的一個常量
ReflectionClass::getConstants — 獲取一組常量
ReflectionClass::getConstructor — 獲取類的構(gòu)造函數(shù)
ReflectionClass::getDefaultProperties — 獲取默認(rèn)屬性
ReflectionClass::getDocComment — 獲取文檔注釋
ReflectionClass::getEndLine — 獲取最后一行的行數(shù)
ReflectionClass::getExtension — 根據(jù)已定義的類獲取所在擴展的 ReflectionExtension 對象
ReflectionClass::getExtensionName — 獲取定義的類所在的擴展的名稱
ReflectionClass::getFileName — 獲取定義類的文件名
ReflectionClass::getInterfaceNames — 獲取接口(interface)名稱
ReflectionClass::getInterfaces — 獲取接口
ReflectionClass::getMethod — 獲取一個類方法的 ReflectionMethod。
ReflectionClass::getMethods — 獲取方法的數(shù)組
ReflectionClass::getModifiers — 獲取類的修飾符
ReflectionClass::getName — 獲取類名
ReflectionClass::getNamespaceName — 獲取命名空間的名稱
ReflectionClass::getParentClass — 獲取父類
ReflectionClass::getProperties — 獲取一組屬性
ReflectionClass::getProperty — 獲取類的一個屬性的 ReflectionProperty
ReflectionClass::getReflectionConstant — Gets a ReflectionClassConstant for a class's constant
ReflectionClass::getReflectionConstants — Gets class constants
ReflectionClass::getShortName — 獲取短名
ReflectionClass::getStartLine — 獲取起始行號
ReflectionClass::getStaticProperties — 獲取靜態(tài)(static)屬性
ReflectionClass::getStaticPropertyValue — 獲取靜態(tài)(static)屬性的值
ReflectionClass::getTraitAliases — 返回 trait 別名的一個數(shù)組
ReflectionClass::getTraitNames — 返回這個類所使用 traits 的名稱的數(shù)組
ReflectionClass::getTraits — 返回這個類所使用的 traits 數(shù)組
ReflectionClass::hasConstant — 檢查常量是否已經(jīng)定義
ReflectionClass::hasMethod — 檢查方法是否已定義
ReflectionClass::hasProperty — 檢查屬性是否已定義
ReflectionClass::implementsInterface — 接口的實現(xiàn)
ReflectionClass::inNamespace — 檢查是否位于命名空間中
ReflectionClass::isAbstract — 檢查類是否是抽象類(abstract)
ReflectionClass::isAnonymous — 檢查類是否是匿名類
ReflectionClass::isCloneable — 返回了一個類是否可復(fù)制
ReflectionClass::isFinal — 檢查類是否聲明為 final
ReflectionClass::isInstance — 檢查類的實例
ReflectionClass::isInstantiable — 檢查類是否可實例化
ReflectionClass::isInterface — 檢查類是否是一個接口(interface)
ReflectionClass::isInternal — 檢查類是否由擴展或核心在內(nèi)部定義
ReflectionClass::isIterateable — 檢查是否可迭代(iterateable)
ReflectionClass::isSubclassOf — 檢查是否為一個子類
ReflectionClass::isTrait — 返回了是否為一個 trait
ReflectionClass::isUserDefined — 檢查是否由用戶定義的
ReflectionClass::newInstance — 從指定的參數(shù)創(chuàng)建一個新的類實例
ReflectionClass::newInstanceArgs — 從給出的參數(shù)創(chuàng)建一個新的類實例。
ReflectionClass::newInstanceWithoutConstructor — 創(chuàng)建一個新的類實例而不調(diào)用它的構(gòu)造函數(shù)
ReflectionClass::setStaticPropertyValue — 設(shè)置靜態(tài)屬性的值
ReflectionClass::__toString — 返回 ReflectionClass 對象字符串的表示形式。

使用 Reflection::export() 獲取類信息

$prodClass = new ReflectionClass('Student');
Reflection::export($prodClass);

打印結(jié)果

Class [ class Student ] {
    @@ D:\wamp\www\test2.php 3-29
    - Constants [0] { }
    - Static properties [0] { }
    - Static methods [0] { }
    - Properties [3] {
        Property [ public $name ]
        Property [ protected $age ]
        Property [ private $sex ]
    }
    - Methods [4] {
        Method [ public method __construct ] {
            @@ D:\wamp\www\test2.php 8 - 13
            - Parameters [3] {
                Parameter #0 [ $name ]
                Parameter #1 [ $age ]
                Parameter #2 [ $sex ]
            }
        }
        Method [ public method setName ] {
            @@ D:\wamp\www\test2.php 15 - 18
            - Parameters [1] {
                Parameter #0 [ $name ]
            }
        }
        Method [ protected method setAge ] {
            @@ D:\wamp\www\test2.php 20 - 23
            - Parameters [1] {
                Parameter #0 [ $age ]
            }
        }
        Method [ private method setSex ] {
            @@ D:\wamp\www\test2.php 25 - 28
            - Parameters [1] {
                Parameter #0 [ $sex ]
            }
        }
    }
}

創(chuàng)建 ReflectionClass對象后,就可以使用 Reflection 工具類輸出 Student 類的相關(guān)信息。Reflection::export() 可以格式化和輸出任何實現(xiàn) Reflector 接口的類的實例。

檢查類

前面我們了解的 ReflectionClass 工具類,知道此類提供了很多的工具方法用于獲取類的信息。例如,我們可以獲取到 Student 類的類型,是否可以實例化

工具函數(shù)

function classData(ReflectionClass $class) {
    $details = '';
    $name = $class->getName();          // 返回要檢查的類名
    if ($class->isUserDefined()) {      // 檢查類是否由用戶定義
        $details .= "$name is user defined" . PHP_EOL;
    }
    if ($class->isInternal()) {         // 檢查類是否由擴展或核心在內(nèi)部定義
        $details .= "$name is built-in" . PHP_EOL;
    }
    if ($class->isInterface()) {        // 檢查類是否是一個接口
        $details .= "$name is interface" . PHP_EOL;
    }
    if ($class->isAbstract()) {         // 檢查類是否是抽象類
        $details .= "$name is an abstract class" . PHP_EOL;
    }
    if ($class->isFinal()) {            // 檢查類是否聲明為 final
        $details .= "$name is a final class" . PHP_EOL;
    }
    if ($class->isInstantiable()) {     // 檢查類是否可實例化
        $details .= "$name can be instantiated" . PHP_EOL;
    } else {
        $details .= "$name can not be instantiated" . PHP_EOL;
    }
    return $details;
}

$prodClass = new ReflectionClass('Student');
print classData($prodClass);

打印結(jié)果

Student is user defined
Student can be instantiated

除了獲取類的相關(guān)信息,還可以獲取 ReflectionClass 對象提供自定義類所在的文件名及文件中類的起始和終止行等相關(guān)源代碼信息。

function getClassSource(ReflectionClass $class) {
    $path  = $class->getFileName();  // 獲取類文件的絕對路徑
    $lines = @file($path);           // 獲得由文件中所有行組成的數(shù)組
    $from  = $class->getStartLine(); // 提供類的起始行
    $to    = $class->getEndLine();   // 提供類的終止行
    $len   = $to - $from + 1;
    return implode(array_slice($lines, $from - 1, $len));
}

$prodClass = new ReflectionClass('Student');
var_dump(getClassSource($prodClass));

打印結(jié)果

string 'class Student {
    public    $name;
    protected $age;
    private   $sex;

    public function __construct($name, $age, $sex)
    {
        $this->setName($name);
        $this->setAge($age);
        $this->setSex($sex);
    }

    public function setName($name)
    {
        $this->name = $name;
    }

    protected function setAge($age)
    {
        $this->age = $age;
    }

    private function setSex($sex)
    {
        $this->sex = $sex;
    }
}
' (length=486)

我們看到 getClassSource 接受一個 ReflectionClass 對象作為它的參數(shù),并返回相應(yīng)類的源代碼。該函數(shù)忽略了錯誤處理,在實際中應(yīng)該要檢查參數(shù)和結(jié)果代碼!

檢查方法

類似于檢查類,ReflectionMethod 對象可以用于檢查類中的方法。

獲得 ReflectionMethod 對象的方法有兩種:

第一種是通過 ReflectionClass::getMethods() 獲得 ReflectionMethod 對象的數(shù)組,這種方式的好處是不用提前知道方法名,會返回類中所有方法的 ReflectionMethod  對象。

第二種是直接使用 ReflectionMethod  類實例化對象,這種方式只能獲取一個類方法對象,需要提前知道方法名。

ReflectionMethod 對象的工具方法:

ReflectionMethod::__construct — ReflectionMethod 的構(gòu)造函數(shù)
ReflectionMethod::export — 輸出一個回調(diào)方法
ReflectionMethod::getClosure — 返回一個動態(tài)建立的方法調(diào)用接口,譯者注:可以使用這個返回值直接調(diào)用非公開方法。
ReflectionMethod::getDeclaringClass — 獲取反射函數(shù)調(diào)用參數(shù)的類表達(dá)
ReflectionMethod::getModifiers — 獲取方法的修飾符
ReflectionMethod::getPrototype — 返回方法原型 (如果存在)
ReflectionMethod::invoke — Invoke
ReflectionMethod::invokeArgs — 帶參數(shù)執(zhí)行
ReflectionMethod::isAbstract — 判斷方法是否是抽象方法
ReflectionMethod::isConstructor — 判斷方法是否是構(gòu)造方法
ReflectionMethod::isDestructor — 判斷方法是否是析構(gòu)方法
ReflectionMethod::isFinal — 判斷方法是否定義 final
ReflectionMethod::isPrivate — 判斷方法是否是私有方法
ReflectionMethod::isProtected — 判斷方法是否是保護(hù)方法 (protected)
ReflectionMethod::isPublic — 判斷方法是否是公開方法
ReflectionMethod::isStatic — 判斷方法是否是靜態(tài)方法
ReflectionMethod::setAccessible — 設(shè)置方法是否訪問
ReflectionMethod::__toString — 返回反射方法對象的字符串表達(dá)

ReflectionClass::getMethods()

我們可以通過 ReflectionClass::getMethods() 獲得 ReflectionMethod 對象的數(shù)組。

$prodClass = new ReflectionClass('Student');
$methods = $prodClass->getMethods();
var_dump($methods);

打印結(jié)果

array (size=4)
  0 => &
    object(ReflectionMethod)[2]
      public 'name' => string '__construct' (length=11)
      public 'class' => string 'Student' (length=7)
  1 => &
    object(ReflectionMethod)[3]
      public 'name' => string 'setName' (length=7)
      public 'class' => string 'Student' (length=7)
  2 => &
    object(ReflectionMethod)[4]
      public 'name' => string 'setAge' (length=6)
      public 'class' => string 'Student' (length=7)
  3 => &
    object(ReflectionMethod)[5]
      public 'name' => string 'setSex' (length=6)
      public 'class' => string 'Student' (length=7)

可以看到我們獲取到了 Student 的 ReflectionMethod 對象數(shù)組,每個元素是一個對象,其中有兩個公共的屬性,name 為方法名,class 為所屬類。我們可以調(diào)用對象方法來獲取方法的信息。

ReflectionMethod

直接使用 ReflectionMethod 類獲取類方法有關(guān)信息

$method = new ReflectionMethod('Student', 'setName');
var_dump($method);

打印結(jié)果

object(ReflectionMethod)[1]
  public 'name' => string 'setName' (length=7)
  public 'class' => string 'Student' (length=7)

注意

在PHP5中,如果被檢查的方法只返回對象(即使對象是通過引用賦值或傳遞的),那么 ReflectionMethod::retursReference() 不會返回 true。只有當(dāng)被檢測的方法已經(jīng)被明確聲明返回引用(在方法名前面有&符號)時,ReflectionMethod::returnsReference() 才返回 true。

檢查方法參數(shù)

在PHP5中,聲明類方法時可以限制參數(shù)中對象的類型,因此檢查方法的參數(shù)變得非常必要。

類似于檢查方法,ReflectionParameter 對象可以用于檢查類中的方法,該對象可以告訴你參數(shù)的名稱,變量是否可以按引用傳遞,還可以告訴你參數(shù)類型提示和方法是否接受空值作為參數(shù)。

獲得 ReflectionParameter 對象的方法有同樣兩種,這和獲取 ReflectionMethod 對象非常類似:

第一種是通過 ReflectionMethod::getParameters() 方法返回 ReflectionParameter 對象數(shù)組,這種方法可以獲取到一個方法的全部參數(shù)對象。

第二種是直接使用 ReflectionParameter  類實例化獲取對象,這種方法只能獲取到單一參數(shù)的對象。

ReflectionParameter 對象的工具方法:

ReflectionParameter::allowsNull — Checks if null is allowed
ReflectionParameter::canBePassedByValue — Returns whether this parameter can be passed by value
ReflectionParameter::__clone — Clone
ReflectionParameter::__construct — Construct
ReflectionParameter::export — Exports
ReflectionParameter::getClass — Get the type hinted class
ReflectionParameter::getDeclaringClass — Gets declaring class
ReflectionParameter::getDeclaringFunction — Gets declaring function
ReflectionParameter::getDefaultValue — Gets default parameter value
ReflectionParameter::getDefaultValueConstantName — Returns the default value's constant name if default value is constant or null
ReflectionParameter::getName — Gets parameter name
ReflectionParameter::getPosition — Gets parameter position
ReflectionParameter::getType — Gets a parameter's type
ReflectionParameter::hasType — Checks if parameter has a type
ReflectionParameter::isArray — Checks if parameter expects an array
ReflectionParameter::isCallable — Returns whether parameter MUST be callable
ReflectionParameter::isDefaultValueAvailable — Checks if a default value is available
ReflectionParameter::isDefaultValueConstant — Returns whether the default value of this parameter is constant
ReflectionParameter::isOptional — Checks if optional
ReflectionParameter::isPassedByReference — Checks if passed by reference
ReflectionParameter::isVariadic — Checks if the parameter is variadic
ReflectionParameter::__toString — To string

ReflectionMethod::getParameters()

同獲取方法,此方法會返回一個數(shù)組,包含方法每個參數(shù)的 ReflectionParameter 對象

$method = new ReflectionMethod('Student', 'setName');
$params = $method->getParameters();
var_dump($params);

打印結(jié)果

array (size=1)
  0 => &
    object(ReflectionParameter)[2]
      public 'name' => string 'name' (length=4)

ReflectionParameter

我們來了解一下這種方式,為了更好的理解,我修改一下 Student 類的 setName方法,增加兩個參數(shù) a, b

...
    public function setName($name, $a, $b)
    {
        $this->name = $name;
    }
...

首先我們看一下 ReflectionParameter 類的構(gòu)造方法

public ReflectionParameter::__construct ( string $function , string $parameter )

可以看到該類實例化時接收兩個參數(shù):

$function:當(dāng)需要獲取函數(shù)為公共函數(shù)時只需傳函數(shù)名稱即可。當(dāng)該函數(shù)是某個類方法時,需要傳遞一個數(shù)組,格式為:array('class', 'function')。

$parameter:這個參數(shù)可以傳遞兩種,第一種為參數(shù)名(無$符號),第二種為參數(shù)索引。注意:無論是參數(shù)名還是索引,該參數(shù)都必須存在,否則會報錯。

下面舉例:

$params = new ReflectionParameter(array('Student', 'setName'), 1);
var_dump($params);

打印結(jié)果

object(ReflectionParameter)[1]
  public 'name' => string 'a' (length=1)

我們再定義一個函數(shù)測試一下

function foo($a, $b, $c) { }
$reflect = new ReflectionParameter('foo', 'c');
var_dump($reflect);

打印結(jié)果

object(ReflectionParameter)[2]
  public 'name' => string 'c' (length=1)

結(jié)語

php的反射API功能非常的強大,它可以將一個類的詳細(xì)信息獲取出來。我們可以通過反射API編寫個類來動態(tài)調(diào)用Module對象,該類可以自由加載第三方插件并集成進(jìn)已有的系統(tǒng)。而不需要把第三方的代碼硬編碼進(jìn)原有的代碼中。雖然實際開發(fā)中使用反射情況比較少,但了解反射API對工作中對代碼結(jié)構(gòu)的了解和開發(fā)業(yè)務(wù)模式幫助還是非常大的。此篇博文斷斷續(xù)續(xù)的寫了很久(主要就是懶?。?,如有錯誤與不足歡迎指正,建議??!

以上就是什么是PHP反射API,小編相信有部分知識點可能是我們?nèi)粘9ぷ鲿姷交蛴玫降摹OM隳芡ㄟ^這篇文章學(xué)到更多知識。更多詳情敬請關(guān)注創(chuàng)新互聯(lián)-成都網(wǎng)站建設(shè)公司行業(yè)資訊頻道。

當(dāng)前標(biāo)題:什么是PHP反射API-創(chuàng)新互聯(lián)
分享路徑:http://muchs.cn/article46/dchghg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站設(shè)計公司、企業(yè)網(wǎng)站制作、關(guān)鍵詞優(yōu)化、靜態(tài)網(wǎng)站、響應(yīng)式網(wǎng)站、網(wǎng)站內(nèi)鏈

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站優(yōu)化排名