成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Laravel源碼閱讀(前奏-反射實(shí)例化對(duì)象)

kuangcaibao / 1365人閱讀

摘要:說(shuō)明的核心容器有一部分就是利用反射來(lái)實(shí)現(xiàn)依賴注入時(shí)類的實(shí)例化。這是一個(gè)簡(jiǎn)化版示例。

說(shuō)明
Laravel的核心容器,有一部分就是利用反射來(lái)實(shí)現(xiàn)依賴注入時(shí)類的實(shí)例化。這是一個(gè)簡(jiǎn)化版示例。
代碼 測(cè)試用的類
/**
 * 坦克標(biāo)準(zhǔn): 必須能開(kāi)火
 */
interface Tank
{
    public function fire();
}


/**
 * 59坦克,使用100毫米炮
 */
class Tank59 implements Tank
{
    private $gun = 100;

    public function fire()
    {
        echo $this->gun . PHP_EOL;
    }
}

/**
 * 59加強(qiáng)版,可以使用100毫米炮或120毫米炮,默認(rèn)120毫米炮
 */
class Tank59Plus implements Tank
{
    private $gun;

    public function __construct($gun = 120)
    {
        if($gun != 100 && $gun != 120) {
            throw new Exception("口徑不合適");
        }

        $this->gun = $gun;
    }

    public function fire()
    {
        echo $this->gun . PHP_EOL;
    }
}

/**
 * 59超級(jí)版,可以使用任意口徑的炮,必須提供一門(mén)火炮
 */
class Tank59Super implements Tank
{
    private $gun;

    public function __construct($gun)
    {
        $this->gun = $gun;
    }

    public function fire()
    {
        echo $this->gun . PHP_EOL;
    }
}

/**
 * 坦克營(yíng),裝備59和59加強(qiáng)版,必須提供59和59加強(qiáng)版
 */
class TankArmy implements Tank
{
    private $tank59;
    private $tank59Plus;

    public function __construct(Tank59 $tank59, Tank59Plus $tank59Plus)
    {
        $this->tank59 = $tank59;
        $this->tank59Plus = $tank59Plus;
    }

    public function fire()
    {
        echo $this->tank59->fire();
        echo $this->tank59Plus->fire();
    }
}
容器
/**
 * 兵工廠
 */
class Factory
{
    /**
     * 創(chuàng)建實(shí)體對(duì)象
     */
    public static function build($blueprint)
    {
        //反射,獲取類細(xì)節(jié)
        $reflector = new ReflectionClass($blueprint);

        //無(wú)法創(chuàng)建的類,比如接口,抽象類
        if(!$reflector->isInstantiable()) {
            throw new Exception("提供的不是坦克圖紙,不能制造");
        }

        //獲取類的構(gòu)造方法
        $constructor = $reflector->getConstructor();
        if (is_null($constructor)) {
            //沒(méi)有構(gòu)造方法,直接new
            return new $blueprint;
        }

        $parameters = [];
        //獲取構(gòu)造方法依賴的參數(shù)
        $dependencies = $constructor->getParameters();
        foreach ($dependencies as $dependency) {
     
            if(is_null($dependency->getClass())) {
                //依賴參數(shù)不是對(duì)象
                //如果構(gòu)造方法參數(shù)有默認(rèn)值,獲取默認(rèn)值
                if($dependency->isDefaultValueAvailable()) {
                    $parameters[] = $dependency->getDefaultValue();
                }
            }
            else {
                //依賴參數(shù)是對(duì)象,遞歸創(chuàng)建
                $parameters[] = self::build($dependency->getClass()->name);
            }
        }

        if(!$parameters) {
            //有構(gòu)造方法且構(gòu)造方法有參數(shù),卻沒(méi)有可以提供的實(shí)參,無(wú)法創(chuàng)建
            throw new Exception("坦克缺少必要的零件,不能制造");
        }
        else {
            //使用反射提供的方法創(chuàng)建對(duì)象,傳入?yún)?shù)
            return  $reflector->newInstanceArgs($parameters);
        }
    }
}
測(cè)試 Tank
$tank = Factory::build(Tank::class);
echo $tank->fire();

//輸出
//PHP Fatal error:  Uncaught Exception: 提供的不是坦克圖紙,不能制造 
Tank59
$tank = Factory::build(Tank59::class);
echo $tank->fire();

//輸出
//100
Tank59Plus
$tank = Factory::build(Tank59Plus::class);
echo $tank->fire();

//輸出
//120
Tank59Super
$tank = Factory::build(Tank59Super::class);
echo $tank->fire();

//輸出
//Fatal error: Uncaught Exception: 坦克缺少必要的零件,不能制造
TankArmy
$tank = Factory::build(TankArmy::class);
echo $tank->fire();

//輸出
//100
//120 

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/28627.html

相關(guān)文章

  • Laravel源碼解析之反射的使用

    摘要:本章講解反射類的使用及對(duì)反射的使用。各位很清楚,方法用于解析類,所有方法的實(shí)現(xiàn)一定是在引用的文件內(nèi)。致謝感謝你看到這里,本篇文章源碼解析靠個(gè)人理解。 showImg(https://segmentfault.com/img/bVbhjvY?w=600&h=296); 前言 PHP的反射類與實(shí)例化對(duì)象作用相反,實(shí)例化是調(diào)用封裝類中的方法、成員,而反射類則是拆封類中的所有方法、成員變量,并...

    pinecone 評(píng)論0 收藏0
  • Laravel深入學(xué)習(xí)2 - 控制反轉(zhuǎn)容器

    摘要:控制反轉(zhuǎn)容器控制反轉(zhuǎn)使依賴注入變得更加便捷。有瑕疵控制反轉(zhuǎn)容器是實(shí)現(xiàn)的控制翻轉(zhuǎn)容器的一種替代方案。容器的獨(dú)立使用即使沒(méi)有使用框架,我們?nèi)匀豢梢栽陧?xiàng)目中使用安裝組件來(lái)使用的控制反轉(zhuǎn)容器。在沒(méi)有給定任何信息的情況下,容器是無(wú)法實(shí)例化相關(guān)依賴的。 聲明:本文并非博主原創(chuàng),而是來(lái)自對(duì)《Laravel 4 From Apprentice to Artisan》閱讀的翻譯和理解,當(dāng)然也不是原汁原味...

    worldligang 評(píng)論0 收藏0
  • LaravelLaravel 框架關(guān)鍵技術(shù)解析·讀書(shū)筆記(一)

    摘要:判斷是否存在構(gòu)造函數(shù),不存在直接實(shí)例化,存在則通過(guò)來(lái)獲取輸入函數(shù),并有相應(yīng)的方法解決依賴參數(shù)問(wèn)題,實(shí)現(xiàn)依賴注入。 Laravel 框架關(guān)鍵技術(shù)解析·讀書(shū)筆記(一) 第一章 入口文件 請(qǐng)求訪問(wèn)的入口文件,主要完成幾部分工作,分別是: 自動(dòng)加載函數(shù)的添加 服務(wù)器實(shí)例化與服務(wù)注冊(cè) 路由加載 請(qǐng)求實(shí)例化與路由分發(fā) 相應(yīng)生成與發(fā)送 其中,自動(dòng)加載函數(shù)用于包含引用文件,改文件是composer...

    CocoaChina 評(píng)論0 收藏0
  • Laravel 依賴注入源碼解析

    在 Laravel 的控制器的構(gòu)造方法或者成員方法,都可以通過(guò)類型約束的方式使用依賴注入,如: public function store(Request $request) { //TODO } 這里 $request 參數(shù)就使用了類型約束,Request 是類型約束的類型,它是一個(gè)類:IlluminateHttpRequest. 本文研究 Laravel 的依賴注入原理,為什么這樣定義...

    Donne 評(píng)論0 收藏0
  • 反射在 PHP 中的應(yīng)用

    摘要:反射在每個(gè)面向?qū)ο蟮木幊陶Z(yǔ)言中都存在,它的主要目的就是在運(yùn)行時(shí)分析類或者對(duì)象的狀態(tài),導(dǎo)出或提取出關(guān)于類方法屬性參數(shù)等的詳細(xì)信息,包括注釋。反射是操縱面向?qū)ο蠓缎椭性P偷模捎糜跇?gòu)建復(fù)雜,可擴(kuò)展的應(yīng)用。 反射在每個(gè)面向?qū)ο蟮木幊陶Z(yǔ)言中都存在,它的主要目的就是在運(yùn)行時(shí)分析類或者對(duì)象的狀態(tài),導(dǎo)出或提取出關(guān)于類、方法、屬性、參數(shù)等的詳細(xì)信息,包括注釋。 反射是操縱面向?qū)ο蠓缎椭性P偷?AP...

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

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

0條評(píng)論

kuangcaibao

|高級(jí)講師

TA的文章

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