日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > php >内容正文

php

Pimple - 一个简单的 PHP 依赖注入容器

發(fā)布時間:2025/3/21 php 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Pimple - 一个简单的 PHP 依赖注入容器 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
鏈接
官網(wǎng) WebSite
GitHub - Pimple 這是 Pimple 3.x 的文檔。如果你正在使用 Pimple 1.x ,請查看 Pimple 1.x 文檔。
閱讀 Pimple 1.x 代碼也是學習更多關(guān)于如何創(chuàng)建簡單的依賴注入容器的好方法,新版本的 Pimple 更加關(guān)注性能。

Pimple - 一個簡單的 PHP 依賴注入容器

安裝

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

另外,Pimple 也可作為 PHP C 擴展使用:

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

使用

創(chuàng)建一個容器實例

use Pimple\Container;$container = new Container();

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

定義服務(wù)

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

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

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

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

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

// 獲取 session 對象 $session = $container['session'];// 上述調(diào)用大致等同于以下代碼: // $storage = new SessionStorage('SESSION_ID'); // $session = new Session($storage);

定義工廠服務(wù)

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

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

現(xiàn)在,每次調(diào)用 $container['session'] 會返回一個新的 session 實例。

定義參數(shù)

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

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

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

保護參數(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; });

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

擴展容器

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

use Pimple\Container;class FooProvider implements Pimple\ServiceProviderInterface {public function register(Container $pimple){// register some services and parameters// on $pimple} }

然后,在容器上注冊 Provider

$pimple->register(new FooProvider());

獲取服務(wù)創(chuàng)建方法

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

$container['session'] = function ($c) {return new Session($c['session_storage']); };$sessionFunction = $container->raw('session');

PSR-11 兼容性

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

PSR-11 容器類

Pimple\Psr11\Container 類允許你使用 Psr\Container\ContainerInterface 方法訪問 Pimple 容器的內(nèi)容:

use Pimple\Container; use Pimple\Psr11\Container 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ù)定位

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

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

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

use Monolog\Logger; use Pimple\Psr11\ServiceLocator; use Psr\Container\ContainerInterface; use Symfony\Component\EventDispatcher\EventDispatcher;class MyService {/*** "logger" must be an instance of Psr\Log\LoggerInterface* "event_dispatcher" must be an instance of Symfony\Component\EventDispatcher\EventDispatcherInterface*/private $services;public function __construct(ContainerInterface $services){$this->services = $services;} }$container['logger'] = function ($c) {return new Monolog\Logger(); }; $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ù)實例可能會導(dǎo)致效率低下,因為如果使用集合的類只需要在稍后調(diào)用它的方法時對其進行迭代即可。如果集合中存儲的其中一個服務(wù)與使用該服務(wù)的類之間存在循環(huán)依賴關(guān)系,則也會導(dǎo)致問題。

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

use Pimple\Container; use Pimple\ServiceIterator;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)載請注明出處,謝謝。
原文鏈接地址:http://dryyun.com/2018/04/17/...
作者: dryyun
發(fā)表日期: 2018-04-17 14:30:29

總結(jié)

以上是生活随笔為你收集整理的Pimple - 一个简单的 PHP 依赖注入容器的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。