真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

laravel服務(wù)容器的實(shí)現(xiàn)原理是什么

laravel 服務(wù)容器的實(shí)現(xiàn)原理是什么,很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。

laravel 服務(wù)容器的實(shí)現(xiàn)原理是什么,很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。

什么是服務(wù)容器

成都創(chuàng)新互聯(lián)網(wǎng)站建設(shè)提供從項(xiàng)目策劃、軟件開發(fā),軟件安全維護(hù)、網(wǎng)站優(yōu)化(SEO)、網(wǎng)站分析、效果評(píng)估等整套的建站服務(wù),主營(yíng)業(yè)務(wù)為成都網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站,重慶APP開發(fā)公司以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務(wù)。成都創(chuàng)新互聯(lián)深信只要達(dá)到每一位用戶的要求,就會(huì)得到認(rèn)可,從而選擇與我們長(zhǎng)期合作。這樣,我們也可以走得更遠(yuǎn)!

服務(wù)容器是用來管理類依賴與運(yùn)行依賴注入的工具。Laravel框架中就是使用服務(wù)容器來實(shí)現(xiàn) ** 控制反轉(zhuǎn) ** 和 ** 依賴注入 **。

什么是控制反轉(zhuǎn)(IoC)和依賴注入(DI)控制反轉(zhuǎn)(IoC) 就是說把創(chuàng)建對(duì)象的** 控制權(quán) 進(jìn)行轉(zhuǎn)移,以前創(chuàng)建對(duì)象的主動(dòng)權(quán)和創(chuàng)建時(shí)機(jī)是由自己把控的,而現(xiàn)在這種權(quán)力轉(zhuǎn)移到第三方,也就是 

Laravel ** 中的容器。

依賴注入(DI)則是幫助容器實(shí)現(xiàn)在運(yùn)行中動(dòng)態(tài)的為對(duì)象提供提依賴的資源。

概念容易不太容易讓人理解,舉個(gè)栗子:

//我們構(gòu)建一個(gè)人的類和一個(gè)狗的類 class People{    public $dog = null;    public function __construct()    {        $this->dog = new Dog();    }    public function putDog(){        return $this->dog->dogCall();    }}class Dog{    public function dogCall(){        return '汪汪汪';    }} ``` 這個(gè)人在遛狗,突然遇到了死對(duì)頭,他于是放狗咬人
$people = new People();
$people->putDog();
在這個(gè)操作中,people類要執(zhí)行 putDog() 這個(gè)方法,需要依賴Dog類,一般我們像上面一樣,在people中利用構(gòu)造函數(shù)來添加這個(gè)Dog依賴。如果使用控制反轉(zhuǎn) 依賴注入則是這個(gè)樣子
class People
{

public $dog = null;

public function __construct(Dog $Dog){    $this->dog = $dog;}public function putDog(){    return $this->dog->dogCall();}

}

People類通過構(gòu)造參數(shù)聲明自己需要的 依賴類,由容器自動(dòng)注入。這樣就實(shí)現(xiàn)了程序的有效解耦,好處在這就不多說了。## Laravel容器依賴注入的實(shí)現(xiàn)###### 實(shí)現(xiàn)原理需要了解的知識(shí)點(diǎn):> 閉包(匿名函數(shù)):匿名函數(shù)(Anonymous functions),也叫閉包函數(shù)(closures),允許 臨時(shí)創(chuàng)建一個(gè)沒有指定名稱的函數(shù)> 反射:PHP 5 以上版本具有完整的反射 API,添加了對(duì)類、接口、函數(shù)、方法和擴(kuò)展進(jìn)行反向工程的能力。 此外,反射 API 提供了方法來取出函數(shù)、類和方法中的文檔注釋###### 理解了閉包和反射的基本用法我們來看Laravel中是怎么實(shí)現(xiàn)容器的,下面代碼是我對(duì)laravel框架容器部分代碼的簡(jiǎn)化核心版:
lass Container
{
/**
* 容器綁定,用來裝提供的實(shí)例或者 提供實(shí)例的回調(diào)函數(shù)
* @var array
*/

public $building = [];

/** * 注冊(cè)一個(gè)綁定到容器 */public function bind($abstract, $concrete = null, $shared = false){    if(is_null($concrete)){        $concrete = $abstract;    }    if(!$concrete instanceOf Closure){        $concrete = $this->getClosure($abstract, $concrete);    }    $this->building[$abstract] =  compact("concrete", "shared");}//注冊(cè)一個(gè)共享的綁定 單例public function singleton($abstract, $concrete, $shared = true){    $this->bind($abstract, $concrete, $shared);}/** * 默認(rèn)生成實(shí)例的回調(diào)閉包 * * @param $abstract * @param $concrete * @return Closure */public function getClosure($abstract, $concrete){    return function($c) use($abstract, $concrete){        $method = ($abstract == $concrete)? 'build' : 'make';        return $c->$method($concrete);    };}/** * 生成實(shí)例  */public function make($abstract){    $concrete = $this->getConcrete($abstract);    if($this->isBuildable($concrete, $abstract)){        $object = $this->build($concrete);    }else{        $object = $this->make($concrete);    }    return $object;}/** * 獲取綁定的回調(diào)函數(shù) */public function getConcrete($abstract){    if(! isset($this->building[$abstract])){        return $abstract;    }    return $this->building[$abstract]['concrete'];}/** * 判斷 是否 可以創(chuàng)建服務(wù)實(shí)體 */public function isBuildable($concrete, $abstract){    return $concrete === $abstract || $concrete instanceof Closure;}/** * 根據(jù)實(shí)例具體名稱實(shí)例具體對(duì)象 */public function build($concrete){    if($concrete instanceof Closure){        return $concrete($this);    }    //創(chuàng)建反射對(duì)象    $reflector = new ReflectionClass($concrete);    if( ! $reflector->isInstantiable()){        //拋出異常        throw new \Exception('無法實(shí)例化');    }    $constructor = $reflector->getConstructor();    if(is_null($constructor)){        return new $concrete;    }    $dependencies = $constructor->getParameters();    $instance = $this->getDependencies($dependencies);    return $reflector->newInstanceArgs($instance);}//通過反射解決參數(shù)依賴public function getDependencies(array $dependencies){    $results = [];    foreach( $dependencies as $dependency ){        $results[] = is_null($dependency->getClass())            ?$this->resolvedNonClass($dependency)            :$this->resolvedClass($dependency);    }    return $results;}//解決一個(gè)沒有類型提示依賴public function resolvedNonClass(ReflectionParameter $parameter){    if($parameter->isDefaultValueAvailable()){        return $parameter->getDefaultValue();    }    throw new \Exception('出錯(cuò)');}//通過容器解決依賴public function resolvedClass(ReflectionParameter $parameter){    return $this->make($parameter->getClass()->name);}
}

```

容器的工作流程
接著上面遛狗的例子:
//實(shí)例化容器類 $app = new Container(); //向容器中填充Dog $app->bind('Dog','App\Dog'); //填充People $app->bind('People', 'App\People'); //通過容器實(shí)現(xiàn)依賴注入,完成類的實(shí)例化; $people = $app->make('People'); //調(diào)用方法 echo $people->putDog();上面示例中我們先實(shí)例化容器類,然后使用bind()方法 綁定接口和 生成相應(yīng)的實(shí)例的閉包函數(shù)。然后使用make() 函數(shù)生成實(shí)例對(duì)象,在make()中會(huì)調(diào)用 isBuildable($concrete, $abstract) 來判斷 給定的服務(wù)實(shí)體($concrete參數(shù))是否可以創(chuàng)建,可以創(chuàng)建 就會(huì)調(diào)用 build($concrete) 函數(shù) ,build($concrete)函數(shù)會(huì)判斷傳的參數(shù)是 是** 閉包 還是

 具體類名 **,如果是閉包則直接運(yùn)行,如果是具體類名的話,則通過反射獲取該類的構(gòu)造函數(shù)所需的依賴,完成實(shí)例化。
** 重點(diǎn)理解 下面這幾個(gè)函數(shù)中 反射的用法,應(yīng)該就很好理解了 **

build($concrete) getDependencies(array $dependencies) resolvedNonClass(ReflectionParameter $parameter) resolvedClass(ReflectionParameter $parameter)


本文標(biāo)題:laravel服務(wù)容器的實(shí)現(xiàn)原理是什么
文章分享:http://weahome.cn/article/copoi.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部