php 兩個類 相互呼叫 PHP的反射機制解析

2021-10-12 19:39:02 字數 4636 閱讀 7762

php的反射機制提供了一套反射api,用來訪問和使用類、方法、屬性、引數和注釋等,比如可以通過乙個物件知道這個物件所屬的類,這個類包含哪些方法,這些方法需要傳入什麼引數,每個引數是什麼型別等等,不用建立類的例項也可以訪問類的成員和方法,就算類成員定義為private也可以在外部訪問。
官方文件提供了諸如reflectionclassreflectionmethodreflectionobjectreflectionextension等反射類及相應的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的屬性、方法,會丟擲異常。

訪問非公有成員需要呼叫指定的reflectionpropertyreflectionmethod物件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 對指向結構體型別變數的正確使用。輸入乙個結構體型別變數的成員,並輸出。...