国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

通過(guò)類名動(dòng)態(tài)生成對(duì)象

VEIGHTZ / 2692人閱讀

摘要:保持目前的情況,除動(dòng)態(tài)生成實(shí)例時(shí)需要完全限定類名,并無(wú)其他槽點(diǎn)。本文所討論的根據(jù)類名動(dòng)態(tài)生成對(duì)象,就要無(wú)視當(dāng)前所在或引入的名字空間,必須使用完全限定類名形式。作為對(duì)比,不能動(dòng)態(tài)生成對(duì)象。

轉(zhuǎn)載請(qǐng)注明文章出處:https://tlanyan.me/dynamic-ne...
問(wèn)題

前幾天有人在PHP的QQ群里問(wèn)生成對(duì)象的問(wèn)題:

use AB;
$b = new B();  // 正確
$str = "B";
$b = new $str(); // 錯(cuò)誤,提示:類"B"未找到

類似問(wèn)題五六年前碰到過(guò),因此印象深刻。熱心提示要用 "完全限定類名" 形式,可惜連說(shuō)兩遍,提問(wèn)題的人都沒(méi)理解我說(shuō)的(或者認(rèn)為我的回復(fù)與其問(wèn)題無(wú)關(guān)):

不得已下,寫下示范代碼并 @ 提問(wèn)題的人,終于讓其明白:

原理

問(wèn)題解決了,背后的原理是什么?

從人的角度看,代碼意圖非常明顯:動(dòng)態(tài)生成類B的實(shí)例。但從執(zhí)行引擎的角度,完全是另外一回事。其實(shí)new $classname()背后的運(yùn)作行為類似于:

// 偽代碼
if (class_exists($str)) {
  $b = new $str();
  return $b;
}
throw ClassNotFoundException;

// 或者用反射
try {
  $reflectionClass = new ReflectionClass($str);
  $b = $reflectionClass.newInstance();
  return $b;
}
throw ClassNotFoundException;

要根據(jù)類名動(dòng)態(tài)生成示例,首先要判斷類是否存在吧?PHP中與之相關(guān)的是class_exists函數(shù)和ReflectionClass類。在上面的例子中,只傳入字符串 "B"class_exists回返回true嗎?

答案是否定的。class_existsReflectionClass只會(huì)在全局類列表中根據(jù)名字查找,不會(huì)理會(huì)調(diào)用函數(shù)所在(或引入)的名字空間。同理,如果使用use引入類名并做別名(as),別名類在class_exists中也會(huì)返回false

那么PHP能否改進(jìn)一下class_existsReflectionClass的行為,讓其根據(jù)當(dāng)前上下文判斷?

可以這么做,但是代價(jià)很大,原因包括:

class_existsReflectionClass都沒(méi)有指示程序上下文Context的參數(shù);

PHP比較坑的一點(diǎn):類名不會(huì)像函數(shù)、常量一樣往上逐級(jí)查找;

如果存在多個(gè)同名的類,加載哪個(gè)?如以下代碼所示:

不管采取哪種行為,都會(huì)招致吐槽。

保持目前的情況,除動(dòng)態(tài)生成實(shí)例時(shí)需要完全限定類名,并無(wú)其他槽點(diǎn)。并且實(shí)現(xiàn)上簡(jiǎn)單,行為明確且一致。

總結(jié)

作為一門腳本語(yǔ)言,PHP非常的靈活,但也會(huì)帶來(lái)一些使用上的困惑。本文所討論的根據(jù)類名動(dòng)態(tài)生成對(duì)象,就要無(wú)視當(dāng)前所在或引入的名字空間,必須使用完全限定類名形式。

作為對(duì)比,C++不能動(dòng)態(tài)生成對(duì)象。Java要用Class.forName的方式獲取class對(duì)象,然后再調(diào)用構(gòu)造函數(shù)生成。Java不能直接new類名,避免了PHP中的坑,但Class.forName同樣需要完全限定類名,避免不明確行為。

參考

PHP回顧之反射

PHP中的重載

Using namespaces: fallback to global function/constant

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/30910.html

相關(guān)文章

  • 【干貨】JDK動(dòng)態(tài)代理的實(shí)現(xiàn)原理以及如何手寫一個(gè)JDK動(dòng)態(tài)代理

    摘要:代理模式從類型上來(lái)說(shuō),可以分為靜態(tài)代理和動(dòng)態(tài)代理兩種類型。然而今天的重點(diǎn)是我們都知道牛逼轟轟的的實(shí)現(xiàn)的一種方式是使用的動(dòng)態(tài)代理另一種是,大部分人也會(huì)用的動(dòng)態(tài)代理,不過(guò)沒(méi)有研究過(guò)的動(dòng)態(tài)代理到底是怎么實(shí)現(xiàn)的。 動(dòng)態(tài)代理 代理模式是設(shè)計(jì)模式中非常重要的一種類型,而設(shè)計(jì)模式又是編程中非常重要的知識(shí)點(diǎn),特別是在業(yè)務(wù)系統(tǒng)的重構(gòu)中,更是有舉足輕重的地位。代理模式從類型上來(lái)說(shuō),可以分為靜態(tài)代理和動(dòng)態(tài)代...

    forsigner 評(píng)論0 收藏0
  • Java動(dòng)態(tài)代理深度解析

    摘要:動(dòng)態(tài)代理深度解析引言說(shuō)起動(dòng)態(tài)代理,很多人可能都沒(méi)有直接去使用過(guò)。因?yàn)榈膭?dòng)態(tài)代理只能代理接口,而不能代理原始的類。接下來(lái)是真正壓軸的環(huán)節(jié),實(shí)現(xiàn)自己的動(dòng)態(tài)代理類。 Java動(dòng)態(tài)代理深度解析 引言 說(shuō)起動(dòng)態(tài)代理,很多人可能都沒(méi)有直接去使用過(guò)。但是只要用過(guò)Spring,那動(dòng)態(tài)代理就是一個(gè)是個(gè)繞不過(guò)的坎,因?yàn)镾pring的核心特性之一AOP就是基于動(dòng)態(tài)代理來(lái)實(shí)現(xiàn)的,那么什么情況下需要用到動(dòng)態(tài)代理...

    whinc 評(píng)論0 收藏0
  • 如何根據(jù)動(dòng)態(tài)SQL代碼自動(dòng)生成DTO

    摘要:如何修改代碼為了盡量減少程序員的工作,我們的代碼生成器在生成完后,還需要將方法的返回值自動(dòng)修改成這個(gè)類。具體的實(shí)現(xiàn)到此為止,基本上代碼生成器的主要障礙都有了相應(yīng)的處理辦法。 當(dāng)前的狀況 一般做數(shù)據(jù)庫(kù)相關(guān)開(kāi)發(fā), 除非學(xué)習(xí), 否則很少有人愿意直接使用JDBC。本來(lái)Java代碼就比較啰嗦了,而直接用JDBC寫代碼之啰嗦簡(jiǎn)直有些令人發(fā)狂!所以在實(shí)際開(kāi)發(fā)過(guò)程中,我們通常都會(huì)使用一些框架/庫(kù)來(lái)幫助...

    weij 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<