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

資訊專欄INFORMATION COLUMN

Pimple - 一個(gè)簡(jiǎn)單的 PHP 依賴注入容器

wemall / 2352人閱讀

摘要:服務(wù)通過匿名函數(shù)定義,返回一個(gè)對(duì)象的實(shí)例定義一些服務(wù)請(qǐng)注意,匿名函數(shù)可以訪問當(dāng)前容器實(shí)例,從而允許引用其他服務(wù)或參數(shù)。如果要為所有調(diào)用返回不同的實(shí)例,請(qǐng)使用方法包裝你的匿名函數(shù)。

鏈接  
官網(wǎng) WebSite
GitHub - Pimple
這是 Pimple 3.x 的文檔。如果你正在使用 Pimple 1.x ,請(qǐng)查看 Pimple 1.x 文檔。
閱讀 Pimple 1.x 代碼也是學(xué)習(xí)更多關(guān)于如何創(chuàng)建簡(jiǎn)單的依賴注入容器的好方法,新版本的 Pimple 更加關(guān)注性能。

Pimple - 一個(gè)簡(jiǎn)單的 PHP 依賴注入容器

安裝

在你的項(xiàng)目中使用 Pimple 之前,將其添加到你的 composer.json 文件中:
$ ./composer.phar require pimple/pimple ~3.0

另外,Pimple 也可作為 PHP C 擴(kuò)展使用:

$ git clone https://github.com/silexphp/Pimple  
$ cd Pimple/ext/pimple  
$ phpize  
$ ./configure  
$ make  
$ make install  
使用

創(chuàng)建一個(gè)容器實(shí)例

use PimpleContainer;

$container = new Container();

與許多其他依賴注入容器一樣,Pimple 管理兩種不同類型的數(shù)據(jù):服務(wù)參數(shù)

定義服務(wù)

服務(wù)是一個(gè)對(duì)象,它可以作為一個(gè)龐大系統(tǒng)的一部分,一些服務(wù)的例子:數(shù)據(jù)庫連接,模板引擎,郵件服務(wù)。幾乎所有的全局對(duì)象都可以成為一項(xiàng)服務(wù)。

服務(wù)通過匿名函數(shù)定義,返回一個(gè)對(duì)象的實(shí)例

// 定義一些服務(wù)
$container["session_storage"] = function ($c) {
    return new SessionStorage("SESSION_ID");
};

$container["session"] = function ($c) {
    return new Session($c["session_storage"]);
};

請(qǐng)注意,匿名函數(shù)可以訪問當(dāng)前容器實(shí)例,從而允許引用其他服務(wù)或參數(shù)。
由于只有在獲取對(duì)象時(shí)才創(chuàng)建對(duì)象,因此定義的順序無關(guān)緊要。

使用定義的服務(wù)也非常簡(jiǎn)單:

// 獲取 session 對(duì)象
$session = $container["session"];

// 上述調(diào)用大致等同于以下代碼:
// $storage = new SessionStorage("SESSION_ID");
// $session = new Session($storage);
定義工廠服務(wù)

默認(rèn)情況下,每次獲得服務(wù)時(shí),Pimple 都會(huì)返回相同的實(shí)例。如果要為所有調(diào)用返回不同的實(shí)例,請(qǐng)使用 factory() 方法包裝你的匿名函數(shù)。

$container["session"] = $container->factory(function ($c) {
    return new Session($c["session_storage"]);
});

現(xiàn)在,每次調(diào)用 $container["session"] 會(huì)返回一個(gè)新的 session 實(shí)例。

定義參數(shù)

定義參數(shù)允許從外部簡(jiǎn)化容器的配置并存儲(chǔ)全局值

// 定義一些參數(shù)
$container["cookie_name"] = "SESSION_ID";
$container["session_storage_class"] = "SessionStorage";

你現(xiàn)在可以很輕松的通過重寫 session_storage_class 參數(shù)而不是重新定義服務(wù)定義來更改 cookie 名稱。

保護(hù)參數(shù)

由于 Pimple 將匿名函數(shù)看作服務(wù)定義,因此需要使用 protect() 方法將匿名函數(shù)包裝為參數(shù):

$container["random_func"] = $container->protect(function () {
    return rand();
});
修改已經(jīng)定義的服務(wù)

在某些情況下,你可能需要在定義服務(wù)定義后修改它。在你的服務(wù)被創(chuàng)建后,你可以使用 extend() 方法添加額外的代碼:

$container["session_storage"] = function ($c) {
    return new $c["session_storage_class"]($c["cookie_name"]);
};

$container->extend("session_storage", function ($storage, $c) {
    $storage->...();

    return $storage;
});

第一個(gè)參數(shù)是要擴(kuò)展的服務(wù)的名稱,第二個(gè)參數(shù)是訪問對(duì)象實(shí)例和容器的函數(shù)。

擴(kuò)展容器

如果你反復(fù)使用相同的庫,可能希望將一個(gè)項(xiàng)目中的某些服務(wù)重用到下一個(gè)項(xiàng)目,通過實(shí)現(xiàn) PimpleServiceProviderInterface 接口,打包你的服務(wù)到 Provider 程序中

use PimpleContainer;

class FooProvider implements PimpleServiceProviderInterface
{
    public function register(Container $pimple)
    {
        // register some services and parameters
        // on $pimple
    }
}

然后,在容器上注冊(cè) Provider

$pimple->register(new FooProvider());
獲取服務(wù)創(chuàng)建方法

當(dāng)你訪問一個(gè)對(duì)象時(shí),Pimple 自動(dòng)調(diào)用你定義的匿名函數(shù),為你創(chuàng)建服務(wù)對(duì)象。如果你想獲得這個(gè)函數(shù)的原始訪問權(quán)限,你可以使用 raw()方法:

$container["session"] = function ($c) {
    return new Session($c["session_storage"]);
};

$sessionFunction = $container->raw("session");
PSR-11 兼容性

由于歷史原因,Container 類沒有實(shí)現(xiàn) PSR-11 ContainerInterface。然而,Pimple 提供了一個(gè)輔助類,它可以讓你從 Pimple 容器類中解耦你的代碼

PSR-11 容器類

PimplePsr11Container 類允許你使用 PsrContainerContainerInterface 方法訪問 Pimple 容器的內(nèi)容:

use PimpleContainer;
use PimplePsr11Container as PsrContainer;

$container = new Container();
$container["service"] = function ($c) {
    return new Service();
};
$psr11 = new PsrContainer($container);

$controller = function (PsrContainer $container) {
    $service = $container->get("service");
};
$controller($psr11);
使用 PSR-11 服務(wù)定位

有時(shí)候,服務(wù)需要訪問其他幾個(gè)服務(wù),而不必確定所有這些服務(wù)都將被實(shí)際使用。在這些情況下,你可能希望懶加載這些服務(wù)。

傳統(tǒng)的解決方案是注入整個(gè)服務(wù)容器來獲得真正需要的服務(wù)。但是,這不被推薦,因?yàn)樗狗?wù)對(duì)應(yīng)用程序的其他部分的訪問過于寬泛,并且隱藏了它們的實(shí)際依賴關(guān)系。

ServiceLocator 旨在通過訪問一組預(yù)定義的服務(wù)來解決此問題,同時(shí)僅在實(shí)際需要時(shí)才實(shí)例化它們。
它還允許你以不同于用于注冊(cè)的名稱提供服務(wù)。例如,你可能希望使用一個(gè)對(duì)象,該對(duì)象期望 EventDispatcherInterface 實(shí)例在名稱 event_dispatcher 下可用,而你的事件分派器已在名稱 dispatcher 下注冊(cè)

use MonologLogger;
use PimplePsr11ServiceLocator;
use PsrContainerContainerInterface;
use SymfonyComponentEventDispatcherEventDispatcher;

class MyService
{
    /**
     * "logger" must be an instance of PsrLogLoggerInterface
     * "event_dispatcher" must be an instance of SymfonyComponentEventDispatcherEventDispatcherInterface
     */
    private $services;

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

$container["logger"] = function ($c) {
    return new MonologLogger();
};
$container["dispatcher"] = function () {
    return new EventDispatcher();
};

$container["service"] = function ($c) {
    $locator = new ServiceLocator($c, array("logger", "event_dispatcher" => "dispatcher"));

    return new MyService($locator);
};
懶懶的引用一系列服務(wù)

在數(shù)組中傳遞一組服務(wù)實(shí)例可能會(huì)導(dǎo)致效率低下,因?yàn)槿绻褂眉系念愔恍枰谏院笳{(diào)用它的方法時(shí)對(duì)其進(jìn)行迭代即可。如果集合中存儲(chǔ)的其中一個(gè)服務(wù)與使用該服務(wù)的類之間存在循環(huán)依賴關(guān)系,則也會(huì)導(dǎo)致問題。

ServiceIterator 類可以幫助你解決這些問題。它在實(shí)例化過程中接收服務(wù)名稱列表,并在迭代時(shí)檢索服務(wù)

use PimpleContainer;
use PimpleServiceIterator;

class AuthorizationService
{
    private $voters;

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

    public function canAccess($resource)
    {
        foreach ($this->voters as $voter) {
            if (true === $voter->canAccess($resource) {
                return true;
            }
        }

        return false;
    }
}

$container = new Container();

$container["voter1"] = function ($c) {
    return new SomeVoter();
}
$container["voter2"] = function ($c) {
    return new SomeOtherVoter($c["auth"]);
}
$container["auth"] = function ($c) {
    return new AuthorizationService(new ServiceIterator($c, array("voter1", "voter2"));
}
誰在支持 Pimple ?

Pimple 是由 Symfony 框架的創(chuàng)建者 Fabien Potencier 寫的 ,Pimple 是在 MIT 協(xié)議下發(fā)布的。

原創(chuàng)文章,歡迎轉(zhuǎn)載。轉(zhuǎn)載請(qǐng)注明出處,謝謝。
原文鏈接地址:http://dryyun.com/2018/04/17/...
作者: dryyun
發(fā)表日期: 2018-04-17 14:30:29

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

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

相關(guān)文章

  • 一個(gè)強(qiáng)大PHP5.3依賴注入容器

    摘要:現(xiàn)在我們就可以在構(gòu)造函數(shù)或者任何其他通過服務(wù)容器注入依賴項(xiàng)的地方使用類型提示注入接口創(chuàng)建一個(gè)新的類實(shí)例,此處將注入的實(shí)例。自動(dòng)解析構(gòu)造函數(shù)所需的依賴的服務(wù)容器實(shí)現(xiàn)了接口。 簡(jiǎn)單的服務(wù)容器 一個(gè)簡(jiǎn)單的 php 5.3 依賴注入容器。 項(xiàng)目地址:https://github.com/godruoyi/easy-container Why 目前比較流行的 PHP 容器: Pimple La...

    sf190404 評(píng)論0 收藏0
  • PHP - Pimple 源碼筆記(下)

    摘要:服務(wù)容器接口是的簡(jiǎn)寫,由組織制定的規(guī)范,是開發(fā)的實(shí)踐標(biāo)準(zhǔn)。實(shí)現(xiàn)的容器類源碼很簡(jiǎn)單,主要是傳入變量,然后設(shè)置這個(gè)兩個(gè)方法。原創(chuàng)文章,歡迎轉(zhuǎn)載。原文鏈接地址作者發(fā)表日期 接著上篇 還有一些內(nèi)容沒有寫,上篇已經(jīng)把關(guān)于 Pimple 最主要的代碼分析了一下,這篇主要是關(guān)于 PSR-11 兼容性的分析。 PSR-11 服務(wù)容器接口 PSR PSR 是 PHP Standard Recommend...

    KunMinX 評(píng)論0 收藏0
  • Pimple相關(guān)源碼

    摘要:已經(jīng)有了非常好的的相關(guān)解析,建議先看下一個(gè)簡(jiǎn)單的依賴注入容器讀源碼筆記上讀源碼筆記下這里通過例子補(bǔ)充下核心方法的說明相關(guān)的類型服務(wù)類似單例工廠服務(wù)多個(gè)實(shí)例參數(shù)僅僅是保存一些變量保護(hù)參數(shù)匿名函數(shù)都會(huì)被認(rèn)為服務(wù),但是如果僅僅是想作為一個(gè) 已經(jīng)有了非常好的Pimple的相關(guān)解析,建議先看下:Pimple - 一個(gè)簡(jiǎn)單的 PHP 依賴注入容器讀 PHP - Pimple 源碼筆記(上)讀 PH...

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

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

    worldligang 評(píng)論0 收藏0
  • PHP程序員如何理解依賴注入容器(dependency injection container)

    摘要:代碼這就是控制反轉(zhuǎn)模式。是變量有默認(rèn)值則設(shè)置默認(rèn)值是一個(gè)類,遞歸解析有默認(rèn)值則返回默認(rèn)值從容器中取得以上代碼的原理參考官方文檔反射,具有完整的反射,添加了對(duì)類接口函數(shù)方法和擴(kuò)展進(jìn)行反向工程的能力。 PHP程序員如何理解依賴注入容器(dependency injection container) 背景知識(shí) 傳統(tǒng)的思路是應(yīng)用程序用到一個(gè)Foo類,就會(huì)創(chuàng)建Foo類并調(diào)用Foo類的方法,假如這...

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

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

0條評(píng)論

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