php的反射機制提供了一套反射api,用來訪問和使用類、方法、屬性、引數和注釋等,比如可以通過乙個物件知道這個物件所屬的類,這個類包含哪些方法,這些方法需要傳入什麼引數,每個引數是什麼型別等等,不用建立類的例項也可以訪問類的成員和方法,就算類成員定義為private
也可以在外部訪問。
官方文件提供了諸如reflectionclass
、reflectionmethod
、reflectionobject
、reflectionextension
等反射類及相應的api,用得最多的是reflectionclass
。
為了演示反射效果,首先建立乙個類(假設定義了乙個類user
),並例項化。基於這個例項,反射類可以訪問user
中的屬性和方法。
<?php
/** * 使用者相關類
*/class user
/*** 獲取使用者名稱
* @return string
*/public function getusername()
/*** 設定使用者名稱
* @param string $username
*/public function setusername($username)
/*** 獲取密碼
* @return string
*/private function getpassword()
/*** 設定密碼
* @param string $password
*/private function setpassowrd($password)
}
建立反射類例項
$refclass = new reflectionclass(new user('liulu', '123456'));
// 也可以寫成
$refclass = new reflectionclass('user'); // 將類名user作為引數,建立user類的反射類
反射屬性
$properties = $refclass->getproperties(); // 獲取user類的所有屬性,返回reflectionproperty的陣列
$property = $refclass->getproperty('password'); // 獲取user類的password屬性
//$properties 結果如下:
array (
[0] => reflectionproperty object ( [name] => username [class] => user )
[1] => reflectionproperty object ( [name] => password [class] => user )
)
//$property 結果如下:
reflectionproperty object ( [name] => password [class] => user )
反射方法
$methods = $refclass->getmethods(); // 獲取user類的所有方法,返回reflectionmethod陣列
$method = $refclass->getmethod('getusername'); // 獲取user類的getusername方法
//$methods 結果如下:
array (
[0] => reflectionmethod object ( [name] => __construct [class] => user )
[1] => reflectionmethod object ( [name] => getusername [class] => user )
[2] => reflectionmethod object ( [name] => setusername [class] => user )
[3] => reflectionmethod object ( [name] => getpassword [class] => user )
[4] => reflectionmethod object ( [name] => setpassowrd [class] => user )
)//$method 結果如下:
reflectionmethod object ( [name] => getusername [class] => user )
反射注釋
$classcomment = $refclass->getdoccomment(); // 獲取user類的注釋文件,即定義在類之前的注釋
$methodcomment = $refclass->getmethod('setpassowrd')->getdoccomment(); // 獲取user類中setpassowrd方法的注釋
//$classcomment 結果如下:
/** * 使用者相關類 */
//$methodcomment 結果如下:
/** * 設定密碼 * @param string $password */
反射例項化
$instance = $refclass->newinstance('admin', 123, '***'); // 從指定的引數建立乙個新的類例項
//$instance 結果如下:
user object ( [username] => admin [password:user:private] => 123 )
注:雖然建構函式中是兩個引數,但是newinstance方法接受可變數目的引數,用於傳遞到類的建構函式。
$params = ['xiaoming', 'asdfg'];
$instance = $refclass->newinstanceargs($params); // 從給出的引數建立乙個新的類例項
//$instance 結果如下:
user object ( [username] => xiaoming [password:user:private] => asdfg )
訪問、執行類的公有方法——public
$instance->setusername('admin_1'); // 呼叫user類的例項呼叫setusername方法設定使用者名稱
$username = $instance->getusername(); // 用過user類的例項呼叫getusername方法獲取使用者名稱
echo $username . "n"; // 輸出 admin_1
// 也可以寫成
$refclass->getproperty('username')->setvalue($instance, 'admin_2'); // 通過反射類reflectionproperty設定指定例項的username屬性值
$username = $refclass->getproperty('username')->getvalue($instance); // 通過反射類reflectionproperty獲取username的屬性值
echo $username . "n"; // 輸出 admin_2
// 還可以寫成
$refclass->getmethod('setusername')->invoke($instance, 'admin_3'); // 通過反射類reflectionmethod呼叫指定例項的方法,並且傳送引數
$value = $refclass->getmethod('getusername')->invoke($instance); // 通過反射類reflectionmethod呼叫指定例項的方法
echo $value . "n"; // 輸出 admin_3
訪問、執行類的非公有方法——private、protected
try catch (exception $e)
// 錯誤寫法 結果如下:
reflectionexception: cannot access non-public member user::password in ***.php
不管反射類中定義的屬性、方法是否為public
,都可以獲取到。
直接訪問protected
或則private
的屬性、方法,會丟擲異常。
訪問非公有成員需要呼叫指定的reflectionproperty
或reflectionmethod
物件setaccessible(true)
方法。
四年精華php技術文章整理合集——php框架篇
四年精華php技術文合集——微服務架構篇
四年精華php技術文合集——分布式架構篇
四年精華php技術文合集——高併發場景篇
C 兩個類相互呼叫實現
兩個類a和b實現互相呼叫彼此的方法,如果採用彼此包含對方標頭檔案的方式會出現迴圈引用,所以採用了類的前置宣告的方式 1.class a採用前置宣告的方式宣告class b 2.在classb的標頭檔案中包含class a 的標頭檔案 3.在class a中只能宣告class b型別的指標或者引用 具...
android 兩個應用相互呼叫
個人總結兩個應用相互呼叫 1.靜態廣播 2.動態廣播 3.startactiviy 4.startactiviyforresult 使用packagename 5.startactivityforresult 使用action 1.靜態廣播調起apk 第一步,在將要調起的apk 中androidma...
兩個結構體之間的相互呼叫
指向結構體型別變數的使用 首先讓我們定義結構體 struct stu 再定義指向結構體型別變數的指標變數 struct stu p1,p2 定義指標變數p 1 p 2,分別指向結構體型別變數。引用形式為 指標變數 成員 例7 2 對指向結構體型別變數的正確使用。輸入乙個結構體型別變數的成員,並輸出。...