反思——反思
在面向?qū)ο缶幊讨校瑢ο蟊毁x予了內(nèi)省的能力,這個內(nèi)省的過程就是反射。反思,直觀理解就是根據(jù)目的地找到出發(fā)點和源頭。比如一個裸對象,我們只能通過這個對象知道它的類和方法。反射是指擴(kuò)展和分析PHP程序,導(dǎo)出或呈現(xiàn)關(guān)于類、方法、屬性、參數(shù)等的詳細(xì)信息。,包括注釋,在PHP的運行狀態(tài)下。這種動態(tài)獲取信息、動態(tài)調(diào)用對象方法的功能稱為反射API。
如何使用反射API
& lt?服務(wù)器端編程語言(Professional Hypertext Preprocessor的縮寫)
classperson{
public $ name
public $ gender
publicfunctionsay(){
echo $this->名字,“tis ”,$ this->;性別," rn ";
}
publicfunctionset($name,$value){
回應(yīng)“將$name設(shè)置為$ value rn”;
$this->。$ name = $ value
}
publicfunctionget($name){
if(!isset($ this->;$name)){
回聲“未設(shè)置”;
$this->。$name= "為您設(shè)置默認(rèn)值";
}
返回$this->。$ name
}
}
$ student = new person();
$student->姓名= '湯姆';
$student->性別= '男';
$student->年齡=24歲;
現(xiàn)在,我應(yīng)該怎么做才能得到這個學(xué)生對象的方法和屬性列表?如以下代碼所示:
//獲取對象屬性列表
$ reflect = NewreflectionObject($ student);
$props=$reflect->。getProperties();
foreach($props as$prop){
打印$prop->getName()?!皀”;
}
//獲取對象方法列表
$m=$reflect->。getMethods();
foreach($m as$prop){
打印$prop->getName()。“n”;
}
您也可以使用類函數(shù)而不是反射API來返回對象屬性的關(guān)聯(lián)數(shù)組和更多信息:
//返回對象屬性的關(guān)聯(lián)數(shù)組
var _ dump(get _ object _ var($ student));
//類屬性
var _ dump(get _ class _ vars(get _ class($ student));
//返回類的方法名數(shù)組
var _ dump(get _ class _ methods(get _ class($ student));
如果這個對象是從其他頁面?zhèn)鬟^來的,你怎么知道它屬于哪個類?它可以用一個代碼來完成:
//獲取對象屬性列表所屬的類
echo get _ class($ student);
反射API顯然更強大,甚至可以還原這個類的原型,包括方法的訪問權(quán)限,比如:
//反射得到類的原型
$ obj = NewReflectionClass(' person ');
$ CLaSS name = $ obj->;getName();
$ Methods = $ Properties = array();
foreach($ obj->;getProperties()作為$v)
{
$ Properties[$ v->;GetName()]= $ v;
}
foreach($ obj->;getMethods()作為$v)
{
$ Methods[$ v->;GetName()]= $ v;
}
echo " class { $ className } n { n
is _ array($ Properties)& amp;& ampksort($ Properties);
foreach($ Properties as $ k = & gt;$v)
{
回聲“t”;
echo $v->isPublic()?public ':',$v->。isPrivate()?private ':',
$v->。isProtected()?受保護(hù)的':',
$v->。isStatic()?靜態(tài)“:”;
echo " t { $ k } n
}
回聲“n”;
if(is _ array($ Methods))k sort($ Methods);
foreach($方法為$k = >;$v)
{
echo " TF function { $ k }(){ } n ";
}
echo " } n
輸出如下:
classperson
{
公共性別
publicname
functionget(){}
functionset(){}
functionsay(){}
}
而且PHP手冊里有幾十個反射API??梢哉f反射完全描述了一個類或者對象的原型。反射不僅可以用于類和對象,還可以用于函數(shù)、擴(kuò)展模塊、異常等等。
反射的效果是什么
反射可用于文檔生成。因此,它可以用來掃描文件中的類,并逐個生成描述文檔。
既然反射可以找出一個類的內(nèi)部結(jié)構(gòu),那么是否可以作為鉤子來實現(xiàn)插件功能呢?還是做一個動態(tài)代理?
例如:
& lt?服務(wù)器端編程語言(Professional Hypertext Preprocessor的縮寫)
classmysql {
functionconnect($db){
Echo“連接到數(shù)據(jù)庫$ { db[0]} rn”;
}
}
classsqlproxy {
private $ target
functionconstruct($tar){
$this->。target[]= new $ tar();
}
functioncall($name,$args){
foreach($ this->;目標(biāo)為$obj){
$ r = NewreflectionClass($ obj);
if($ method = $ r->;getMethod($name)){
if($ method->;isPublic()& amp;& amp!$ method->;isAbstract()){
Echo“在方法之前截取LOGrn
$ method->;invoke($obj,$ args);
Echo“方法后截取rn”;
}
}
}
}
}
$ obj = newsql proxy(' MySQL ');
$obj->connect(' member ');
在正常開發(fā)中,使用反射的地方并不多:一個是調(diào)試對象,一個是獲取類信息。在MVC和插件開發(fā)中,反射是很常見的,但是消耗很大,如果能找到替代品就不要濫用。
PHP有Token函數(shù),可以實現(xiàn)一些反射函數(shù)。從簡單靈活的角度來看,最好使用已經(jīng)提供的反射API。
在很多情況下,利用好反射可以讓代碼保持優(yōu)雅簡潔,但是反射也可以破壞類的封裝,因為反射可以強制不應(yīng)該暴露的方法或者屬性,這既是優(yōu)點也是缺點。
1.《reflection PHP高級特性之反射(Reflection)》援引自互聯(lián)網(wǎng),旨在傳遞更多網(wǎng)絡(luò)信息知識,僅代表作者本人觀點,與本網(wǎng)站無關(guān),侵刪請聯(lián)系頁腳下方聯(lián)系方式。
2.《reflection PHP高級特性之反射(Reflection)》僅供讀者參考,本網(wǎng)站未對該內(nèi)容進(jìn)行證實,對其原創(chuàng)性、真實性、完整性、及時性不作任何保證。
3.文章轉(zhuǎn)載時請保留本站內(nèi)容來源地址,http://f99ss.com/yule/1220257.html