手寫PHP API框架(三)之反射介紹
上一篇《手寫PHP API框架之Composer的安裝使用(二)》文章中我們介紹了Composer的安裝使用,這一文我們來介紹一下有關反射的概念介紹。
反射,直覺理解就是根據到達地找到出發地和來源。反射指在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 | 取得預設屬性 |
取得文件註解 | |
取得最後一行的行數 | |
根據已定義的類別取得所在擴充功能的ReflectionExtension 物件 | |
取得定義的類別所在的擴充功能的名稱 | |
取得定義類別的檔案名稱 | |
#取得介面(interface)名稱 | |
使用介面 | |
#取得一個類別方法的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 | |
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 |
檢查類別的實例 | |
檢查類別是否可實例化 | |
檢查類別是否是一個介面(interface) | |
檢查類別是否由擴充或核心在內部定義 | |
Check whether this class is iterable | |
檢查是否可迭代(iterateable) | |
檢查是否為一個子類別 | |
傳回了是否為一個trait | |
檢查是否由使用者定義的 | |
從指定的參數建立一個新的類別實例 | |
從給定的參數建立一個新的類別實例。 | |
#建立一個新的類別實例而不呼叫它的建構子 |
除去強大的ReflectionClass,還有Reflection、ReflectionClassConstant 、ReflectionMethod 、ReflectionFunctionAbstract等等。建議查看手冊:
#反射的實際應用
- ##反射可以用於文件、文件產生。可以用它對文件裡的類別進行掃描,逐個生成描述文檔;
- 既然反射可以探知類別的內部結構,那麼可以用它做hook實現插件功能;
- 可以用來做動態代理,在未知或不確定類別名稱的情況下,動態產生和實例化一些類別和執行方法;
- 依賴注入。對於多次繼承的類,我們可以透過多次反射來探索基類的結構,或是採用遞歸的形式反射,實現實例化所有繼承類,這也是PHP依賴注入的原理。
反射的優點
- #支援反射的語言提供了一些在低階語言中難以實現的執行時間特性。
- 可以在一定程度上避免硬編碼,提供靈活性和通用性。
- 可以作為一個第一類物件來發現並修改原始碼的結構(如程式碼區塊、類別、方法、協定等)。
- 可以在執行時期像對待原始程式碼語句一樣計算符號語法的字串(類似JavaScript的eval()函數),進而可將跟class或function相符的字串轉換成class或function的呼叫或引用。
- 可以建立一個新的語言字節碼解釋器來給程式設計結構一個新的意義或用途。
反射的缺點
- #學習成本高。反射導向的程式設計需要較多的高階知識,包括框架、關係映射和物件交互,以利用更通用的程式碼執行
- 同樣因為反射的概念和語法都比較抽象,過度濫用反射技術會讓程式碼難以被其他人讀懂,不利於合作與交流
- #反射在提高了程式碼彈性的同時,犧牲了一點點運作效率,有一定的消耗
- 反射也會破壞類別的封裝性,把本不該暴露的方法或屬性暴露了出來 ##在平常的開發中,我們用到反射其實不多,為什麼要把它拿到這裡來說呢?一來是我們後面會使用到反射去實現Ioc容器,二來反射也是PHP核心功能之一,在我們流行的框架中十分常見,理解它是很有必要的。
這一節是比較獨立的,在後面的章節我們會使用它。
推薦學習:《
PHP影片教學以上是手寫PHP API框架(三)之反射介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

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

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

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

PHP和Python各有優勢,選擇依據項目需求。 1.PHP適合web開發,尤其快速開發和維護網站。 2.Python適用於數據科學、機器學習和人工智能,語法簡潔,適合初學者。

PHP在電子商務、內容管理系統和API開發中廣泛應用。 1)電子商務:用於購物車功能和支付處理。 2)內容管理系統:用於動態內容生成和用戶管理。 3)API開發:用於RESTfulAPI開發和API安全性。通過性能優化和最佳實踐,PHP應用的效率和可維護性得以提升。

PHP是一種廣泛應用於服務器端的腳本語言,特別適合web開發。 1.PHP可以嵌入HTML,處理HTTP請求和響應,支持多種數據庫。 2.PHP用於生成動態網頁內容,處理表單數據,訪問數據庫等,具有強大的社區支持和開源資源。 3.PHP是解釋型語言,執行過程包括詞法分析、語法分析、編譯和執行。 4.PHP可以與MySQL結合用於用戶註冊系統等高級應用。 5.調試PHP時,可使用error_reporting()和var_dump()等函數。 6.優化PHP代碼可通過緩存機制、優化數據庫查詢和使用內置函數。 7

PHP和Python各有優勢,選擇應基於項目需求。 1.PHP適合web開發,語法簡單,執行效率高。 2.Python適用於數據科學和機器學習,語法簡潔,庫豐富。

PHP仍然具有活力,其在現代編程領域中依然佔據重要地位。 1)PHP的簡單易學和強大社區支持使其在Web開發中廣泛應用;2)其靈活性和穩定性使其在處理Web表單、數據庫操作和文件處理等方面表現出色;3)PHP不斷進化和優化,適用於初學者和經驗豐富的開發者。

PHP和Python各有優劣,選擇取決於項目需求和個人偏好。 1.PHP適合快速開發和維護大型Web應用。 2.Python在數據科學和機器學習領域佔據主導地位。

PHP適合web開發,特別是在快速開發和處理動態內容方面表現出色,但不擅長數據科學和企業級應用。與Python相比,PHP在web開發中更具優勢,但在數據科學領域不如Python;與Java相比,PHP在企業級應用中表現較差,但在web開發中更靈活;與JavaScript相比,PHP在後端開發中更簡潔,但在前端開發中不如JavaScript。

PHP主要是過程式編程,但也支持面向對象編程(OOP);Python支持多種範式,包括OOP、函數式和過程式編程。 PHP適合web開發,Python適用於多種應用,如數據分析和機器學習。
