您好,登錄后才能下訂單哦!
這篇“PHP反射指的是什么”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“PHP反射指的是什么”文章吧。
反射,直觀理解就是根據到達地找到出發地和來源。 反射指在PHP運行狀態中,擴展分析PHP程序,導出或提出關于類、方法、屬性、參數等的詳細信息,包括注釋。這種動態獲取信息以及動態調用對象方法的功能稱為反射API。
不妨先來看一個demo:
<?php
function p($msg, $var)
{
echo($msg.":".print_r($var, true)).PHP_EOL.PHP_EOL;
}
class Demo
{
private $id;
protected $name;
public $skills = [];
public function __construct($id, $name, $skills = [])
{
$this->id = $id;
$this->name = $name;
$this->skills = $skills;
}
public function getName()
{
return $this->name;
}
public function getSkill()
{
p('skill', $this->skills);
}
}
$ref = new ReflectionClass('Demo');
if ($ref->isInstantiable()) {
p('檢查類是否可實例化isInstantiable', null);
}
$constructor = $ref->getConstructor();
p('獲取構造函數getConstructor', $constructor);
$parameters = $constructor->getParameters();
foreach ($parameters as $param) {
p('獲取參數getParameters', $param);
}
if ($ref->hasProperty('name')) {
$attr = $ref->getProperty('name');
p('獲取屬性getProperty', $attr);
}
$attributes = $ref->getProperties();
foreach ($attributes as $row) {
p('獲取屬性列表getProperties', $row->getName());
}
if ($ref->hasMethod('getSkill')) {
$method = $ref->getMethod('getSkill');
p('獲取方法getMethod', $method);
}
$methods = $ref->getMethods();
foreach ($methods as $row) {
p('獲取方法列表getMethods', $row->getName());
}
$instance = $ref->newInstanceArgs([1, 'sai', ['php', 'js']]);
p('newInstanceArgs', $instance);
輸出:
? php git:(main) php reflect.php
檢查類是否可實例化isInstantiable:
獲取構造函數getConstructor:ReflectionMethod Object
(
[name] => __construct
[class] => Demo
)
獲取參數getParameters:ReflectionParameter Object
(
[name] => id
)
獲取參數getParameters:ReflectionParameter Object
(
[name] => name
)
獲取參數getParameters:ReflectionParameter Object
(
[name] => skills
)
獲取屬性getProperty:ReflectionProperty Object
(
[name] => name
[class] => Demo
)
獲取屬性列表getProperties:id
獲取屬性列表getProperties:name
獲取屬性列表getProperties:skills
獲取方法getMethod:ReflectionMethod Object
(
[name] => getSkill
[class] => Demo
)
獲取方法列表getMethods:__construct
獲取方法列表getMethods:getName
獲取方法列表getMethods:getSkill
newInstanceArgs:Demo Object
(
[id:Demo:private] => 1
[name:protected] => sai
[skills] => Array
(
[0] => php
[1] => js
)
)
demo里面就有使用了ReflectionClass類,當然ReflectionClass類不止于這些方法。
更多方法
ReflectionClass類還有更多方法:
方法 | 說明 |
---|---|
ReflectionClass::__construct | 初始化 ReflectionClass 類 |
ReflectionClass::export | 導出一個類 |
ReflectionClass::getConstant | 獲取定義過的一個常量 |
ReflectionClass::getConstants | 獲取一組常量 |
ReflectionClass::getConstructor | 獲取類的構造函數 |
ReflectionClass::getDefaultProperties | 獲取默認屬性 |
ReflectionClass::getDocComment | 獲取文檔注釋 |
ReflectionClass::getEndLine | 獲取最后一行的行數 |
ReflectionClass::getExtension | 根據已定義的類獲取所在擴展的 ReflectionExtension 對象 |
ReflectionClass::getExtensionName | 獲取定義的類所在的擴展的名稱 |
ReflectionClass::getFileName | 獲取定義類的文件名 |
ReflectionClass::getInterfaceNames | 獲取接口(interface)名稱 |
ReflectionClass::getInterfaces | 獲取接口 |
ReflectionClass::getMethod | 獲取一個類方法的 ReflectionMethod。 |
ReflectionClass::getMethods | 獲取方法的數組 |
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 | 獲取靜態(static)屬性 |
ReflectionClass::getStaticPropertyValue | 獲取靜態(static)屬性的值 |
ReflectionClass::getTraitAliases | 返回 trait 別名的一個數組 |
ReflectionClass::getTraitNames | 返回這個類所使用 traits 的名稱的數組 |
ReflectionClass::getTraits | 返回這個類所使用的 traits 數組 |
ReflectionClass::hasConstant | 檢查常量是否已經定義 |
ReflectionClass::hasMethod | 檢查方法是否已定義 |
ReflectionClass::hasProperty | 檢查屬性是否已定義 |
ReflectionClass::implementsInterface | 接口的實現 |
ReflectionClass::inNamespace | 檢查是否位于命名空間中 |
ReflectionClass::isAbstract | 檢查類是否是抽象類(abstract) |
ReflectionClass::isAnonymous | 檢查類是否是匿名類 |
ReflectionClass::isCloneable | 返回了一個類是否可復制 |
ReflectionClass::isFinal | 檢查類是否聲明為 final |
ReflectionClass::isInstance | 檢查類的實例 |
ReflectionClass::isInstantiable | 檢查類是否可實例化 |
ReflectionClass::isInterface | 檢查類是否是一個接口(interface) |
ReflectionClass::isInternal | 檢查類是否由擴展或核心在內部定義 |
ReflectionClass::isIterable | Check whether this class is iterable |
ReflectionClass::isIterateable | 檢查是否可迭代(iterateable) |
ReflectionClass::isSubclassOf | 檢查是否為一個子類 |
ReflectionClass::isTrait | 返回了是否為一個 trait |
ReflectionClass::isUserDefined | 檢查是否由用戶定義的 |
ReflectionClass::newInstance | 從指定的參數創建一個新的類實例 |
ReflectionClass::newInstanceArgs | 從給出的參數創建一個新的類實例。 |
ReflectionClass::newInstanceWithoutConstructor | 創建一個新的類實例而不調用它的構造函數 |
ReflectionClass::setStaticPropertyValue | 設置靜態屬性的值 |
ReflectionClass::__toString | 返回 ReflectionClass 對象字符串的表示形式。 |
除去強大的ReflectionClass,還有Reflection、ReflectionClassConstant 、ReflectionMethod 、ReflectionFunctionAbstract等等。建議查看手冊:
PHP反射
反射的實際應用
反射可以用于文檔、文件生成。可以用它對文件里的類進行掃描,逐個生成描述文檔;
既然反射可以探知類的內部結構,那么可以用它做hook實現插件功能;
可以用于做動態代理,在未知或者不確定類名的情況下,動態生成和實例化一些類和執行方法;
依賴注入。對于多次繼承的類,我們可以通過多次反射探索到基類的結構,或者采用遞歸的形式反射,實現實例化所有繼承類,這也是PHP依賴注入的原理。
反射的優點
支持反射的語言提供了一些在低級語言中難以實現的運行時特性。
可以在一定程度上避免硬編碼,提供靈活性和通用性。
可以作為一個第一類對象發現并修改源代碼的結構(如代碼塊、類、方法、協議等)。
可以在運行時像對待源代碼語句一樣計算符號語法的字符串(類似JavaScript的eval()函數),進而可將跟class或function匹配的字符串轉換成class或function的調用或引用。
可以創建一個新的語言字節碼解釋器來給編程結構一個新的意義或用途。
反射的缺點
學習成本高。面向反射的編程需要較多的高級知識,包括框架、關系映射和對象交互,以利用更通用的代碼執行
同樣因為反射的概念和語法都比較抽象,過多地濫用反射技術會使得代碼難以被其他人讀懂,不利于合作與交流
反射在提高了代碼靈活性的同時,犧牲了一點點運行效率,有一定的消耗
反射也會破壞類的封裝性,把本不該暴露的方法或屬性暴露了出來
以上就是關于“PHP反射指的是什么”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。