国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

目錄
什么是Pimple,為什么在PHP中使用它?
Pimple是如何工作的?
如何安裝Pimple?
如何在Pimple中定義服務(wù)?
如何在Pimple中訪問服務(wù)?
如何在Pimple中共享服務(wù)?
我可以在Pimple中擴(kuò)展服務(wù)嗎?
如何保護(hù)Pimple中的參數(shù)?
如何在一個項目中使用Pimple?
使用Pimple的好處是什么?
首頁 后端開發(fā) php教程 PHP主|用丘疹注入依賴

PHP主|用丘疹注入依賴

Feb 24, 2025 am 08:57 AM

PHP Master | Dependency Injection with Pimple

核心要點(diǎn)

  • 依賴注入是應(yīng)用開發(fā)中的一個關(guān)鍵概念,通過將依賴項注入模塊而不是硬編碼它們,可以編寫更高效、更易維護(hù)的代碼。
  • Pimple是一個簡單的依賴注入容器,它使用PHP的閉包以可管理的方式定義依賴項,有助于保持代碼的可維護(hù)性。
  • 注入依賴項的兩種主要技術(shù)是基于構(gòu)造函數(shù)的依賴注入和基于設(shè)置器的注入,每種技術(shù)都有其自身的優(yōu)缺點(diǎn)。
  • Pimple通過充當(dāng)定義依賴項的容器來支持軟件開發(fā)的DRY(不要重復(fù)自己)原則,避免重復(fù),從而更輕松地管理和集中應(yīng)用程序中的服務(wù)。
  • Pimple還提供高級功能,例如使用共享對象返回相同實(shí)例的能力,以及無需影響原始實(shí)現(xiàn)即可動態(tài)修改現(xiàn)有閉包的能力。

在應(yīng)用程序開發(fā)中,我們嘗試創(chuàng)建獨(dú)立的模塊,以便在未來的項目中重用代碼。但是,創(chuàng)建提供有用功能的完全獨(dú)立的模塊很困難;除非正確管理它們的依賴關(guān)系,否則它們可能會導(dǎo)致維護(hù)噩夢。這就是依賴注入派上用場的地方,因為它使我們能夠注入代碼正常運(yùn)行所需的依賴項,而無需將它們硬編碼到模塊中。Pimple是一個簡單的依賴注入容器,它利用PHP的閉包以可管理的方式定義依賴項。在本文中,我們將探討硬編碼依賴項的問題,依賴注入如何解決這些問題,以及如何使用Pimple來使利用依賴注入的代碼更易于維護(hù)。

具體依賴項的問題

在編寫應(yīng)用程序時,我們會使用許多PHP類。一個類可能需要調(diào)用一個或多個其他類的方法來提供預(yù)期的功能,因此我們說第一個類依賴于其他類。例如:

<?php
class A
{
    public function a1() {
        $b = new B();
        $b->b1();
    }
}

類A依賴于類B。如果類B不可用,則上述代碼將無法工作。此外,每次我們在類中硬編碼對象的創(chuàng)建時,我們都會對該類產(chǎn)生具體的依賴關(guān)系。具體依賴關(guān)系是編寫可測試代碼的障礙。更好的方法是向類A提供類B的對象。這些對象可以通過A的構(gòu)造函數(shù)或setter方法提供。在我們進(jìn)一步討論之前,讓我們來看一個更現(xiàn)實(shí)的場景。

如今,在社交網(wǎng)絡(luò)網(wǎng)站上共享內(nèi)容非常普遍,大多數(shù)網(wǎng)站都在其網(wǎng)站上直接顯示其社交資料提要。假設(shè)我們有一個名為SocialFeeds的類,它從Twitter、Facebook、Google 等社交網(wǎng)站生成提要。創(chuàng)建單獨(dú)的類來處理這些服務(wù)中的每一個。在這里,我們將研究與Twitter交互的類TwitterService。SocialFeeds類使用TwitterService請求Twitter提要。TwitterService與數(shù)據(jù)庫交互以檢索訪問API的特定用戶令牌。令牌傳遞給OAuth類,該類使用提供的令牌檢索提要并將其返回給SocialFeeds類。

<?php
class A
{
    public function a1() {
        $b = new B();
        $b->b1();
    }
}
<?php
class SocialFeeds
{
    public function getSocialFeeds() {
        $twService = new TwitterService();
        echo $twService->getTweets();
    }
}
<?php
class TwitterService
{
    public function getTweets() {
        $db = new DB();
        $query = "Query to get user token from database";
        $token = $db->getQueryResults($query);

        $oauth = new OAuth();
        return $oauth->requestTwitterFeed($token);
    }
}
<?php
class OAuth
{
    public function requestTwitterFeed($token) {
        // Retrieve and return twitter feed using the token         
    }
}

很明顯,SocialFeeds依賴于TwitterService。但是TwitterService依賴于DB和OAuth,因此SocialFeeds間接依賴于DB和OAuth。那么問題是什么呢?SocialFeeds依賴于三個類的具體實(shí)現(xiàn),因此不可能在沒有其他類的真實(shí)實(shí)現(xiàn)的情況下單獨(dú)測試SocialFeeds?;蛘?,假設(shè)我們想使用不同的數(shù)據(jù)庫或不同的OAuth提供程序。在這種情況下,我們必須在整個代碼中用新類替換現(xiàn)有類。

修復(fù)具體依賴項

解決這些依賴項問題的方案很簡單,即在必要時動態(tài)提供對象,而無需使用具體實(shí)現(xiàn)。有兩種類型的技術(shù)可以注入依賴項:基于構(gòu)造函數(shù)的依賴注入和基于設(shè)置器的注入。

基于構(gòu)造函數(shù)的注入

使用基于構(gòu)造函數(shù)的依賴注入,依賴對象是在外部創(chuàng)建的,并作為參數(shù)傳遞給類的構(gòu)造函數(shù)。我們可以將這些對象分配給類變量,并在類內(nèi)任何地方使用。SocialFeeds類的基于構(gòu)造函數(shù)的注入如下所示:

<?php
class DB
{
    public function getQueryResults($query) {
        // Get results from database and return token
    }
}

TwitterService的實(shí)例作為對象傳遞給構(gòu)造函數(shù)。SocialFeeds仍然依賴于TwitterService,但現(xiàn)在我們可以自由地提供不同版本的Twitter服務(wù)提供程序,甚至可以提供用于測試目的的模擬對象。關(guān)于TwitterService,DB和OAuth類也以類似的方式定義。

<?php
class SocialFeeds
{
    public $twService;

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

    public function getSocialFeeds() {
        echo $this->twService->getTweets();
    }
}

基于設(shè)置器的注入

使用基于設(shè)置器的注入,對象是通過setter方法而不是構(gòu)造函數(shù)提供的。以下是SocialFeeds類的基于設(shè)置器的依賴注入實(shí)現(xiàn):

<?php
$db = new DB();
$oauth = new OAuth();
$twService = new TwitterService($db, $oauth);
$socialFeeds = new SocialFeeds($twService);
$socialFeeds->getSocialFeeds();

現(xiàn)在包括DB和OAuth的初始化代碼如下所示:

<?php
class SocialFeeds
{
    public $twService;

    public function getSocialFeeds() {
        echo $this->twService->getTweets();
    }

    public function setTwitterService($twService) {
        $this->twService = $twService;
    }
}

構(gòu)造函數(shù)與設(shè)置器注入

選擇基于構(gòu)造函數(shù)的注入還是基于設(shè)置器的注入取決于您。當(dāng)需要所有依賴項才能實(shí)例化類時,基于構(gòu)造函數(shù)的注入是合適的。當(dāng)并非每次都需要依賴項時,基于設(shè)置器的注入是合適的。

優(yōu)點(diǎn)

  • 構(gòu)造函數(shù) – 只需查看類的構(gòu)造函數(shù)即可識別類的所有依賴項
  • 設(shè)置器 – 添加新的依賴項就像添加新的setter方法一樣簡單,不會破壞現(xiàn)有代碼

缺點(diǎn)

  • 構(gòu)造函數(shù) – 添加新的依賴項會增加構(gòu)造函數(shù)的參數(shù);需要更新整個應(yīng)用程序中的現(xiàn)有代碼以提供新的依賴項
  • 設(shè)置器 – 我們必須手動搜索必要的依賴項,因為它們沒有在任何地方指定

了解了依賴注入和各種注入技術(shù)后,是時候看看Pimple以及它如何融入其中了。

Pimple在DI中的作用

當(dāng)我們已經(jīng)可以使用前面提到的技術(shù)注入依賴項時,您可能想知道為什么需要Pimple。要回答這個問題,我們需要看看DRY原則。

不要重復(fù)自己(DRY)是軟件開發(fā)的一個原則,旨在減少各種信息的重復(fù),這在多層架構(gòu)中特別有用。DRY原則的陳述是“每個知識片段都必須在一個系統(tǒng)中具有單個、明確、權(quán)威的表示”——維基百科

考慮基于構(gòu)造函數(shù)的注入示例。每次我們想要SocialFeed類的對象時,我們都必須重復(fù)實(shí)例化和傳遞其依賴項的整個設(shè)置過程。根據(jù)DRY,應(yīng)避免此類代碼以防止維護(hù)出現(xiàn)問題。Pimple充當(dāng)定義此類依賴項以避免重復(fù)的容器。讓我們來看一個簡單的例子,看看Pimple是如何工作的。

<?php
class A
{
    public function a1() {
        $b = new B();
        $b->b1();
    }
}

創(chuàng)建Pimple的實(shí)例充當(dāng)存儲依賴項的容器。它實(shí)現(xiàn)SPL ArrayAccess接口,因此使用它與使用數(shù)組非常相似。首先,我們定義了一個鍵,該鍵保存我們想要的某個任意類的名稱。然后,我們定義了一個閉包來返回指定類的實(shí)例,該實(shí)例充當(dāng)服務(wù)。請注意,將向$c傳遞容器的實(shí)例,因此我們可以根據(jù)需要引用其他已定義的鍵;每個已定義的參數(shù)或?qū)ο蠖伎赏ㄟ^$c變量在閉包中使用?,F(xiàn)在,每當(dāng)我們想要類的實(shí)例時,我們都可以引用鍵來檢索對象。讓我們將SocialFeeds示例轉(zhuǎn)換為Pimple。Pimple官方網(wǎng)站上的示例顯示了基于構(gòu)造函數(shù)的注入,因此在這里我們將說明基于設(shè)置器的注入。請記住,為了使用Pimple,我們不需要修改前面定義的任何setter方法或代碼——我們只是封裝了邏輯。

<?php
class SocialFeeds
{
    public function getSocialFeeds() {
        $twService = new TwitterService();
        echo $twService->getTweets();
    }
}

DB和OAuth類都是獨(dú)立的模塊,因此我們直接在閉包內(nèi)返回它們的新的實(shí)例。然后,我們使用基于設(shè)置器的注入向TwitterService類添加依賴項。我們已經(jīng)將DB和OAuth類添加到容器中,因此我們可以使用$c['db']和$c['oauth']直接在函數(shù)內(nèi)訪問它們?,F(xiàn)在,依賴項作為服務(wù)封裝在容器內(nèi)。每當(dāng)我們想要使用不同的DB類或不同的OAuth服務(wù)時,我們只需替換容器語句中的類,一切都會完美運(yùn)行。使用Pimple,您只需要在一個地方添加新的依賴項。

高級Pimple用法

在上述場景中,Pimple會在每次請求時從閉包返回每個類的新的實(shí)例。在某些情況下,我們需要使用相同的對象而無需每次都初始化新的實(shí)例,例如連接到數(shù)據(jù)庫就是一個完美的例子。Pimple提供了使用共享對象返回相同實(shí)例的能力,這樣做需要我們通過share()方法指定閉包,如下所示:

<?php
class A
{
    public function a1() {
        $b = new B();
        $b->b1();
    }
}

此外,到目前為止,我們已經(jīng)在Pimple容器中的單個位置定義了所有依賴項。但是,考慮一下我們需要具有其依賴項的服務(wù),但配置方式與原始服務(wù)略有不同的情況。例如,假設(shè)我們需要訪問ORM來實(shí)現(xiàn)TwitterService類的某些功能。我們不能更改現(xiàn)有的閉包,因為它會強(qiáng)制所有現(xiàn)有功能使用ORM。Pimple提供extend()方法來動態(tài)修改現(xiàn)有閉包,而不會影響原始實(shí)現(xiàn)??紤]以下代碼:

<?php
class SocialFeeds
{
    public function getSocialFeeds() {
        $twService = new TwitterService();
        echo $twService->getTweets();
    }
}

現(xiàn)在,我們能夠在特殊情況下使用tweet_service的不同擴(kuò)展版本。第一個參數(shù)是服務(wù)的名稱,第二個參數(shù)是一個函數(shù),該函數(shù)可以訪問對象實(shí)例和容器。實(shí)際上,extend()是動態(tài)添加依賴項以適應(yīng)不同情況的強(qiáng)大方法,但請確保將服務(wù)的擴(kuò)展版本限制在最低限度,因為它會增加重復(fù)代碼的數(shù)量。

總結(jié)

管理依賴項是Web應(yīng)用程序開發(fā)中最重要和最困難的任務(wù)之一。我們可以使用構(gòu)造函數(shù)和setter方法的依賴注入來有效地管理它們。但是,依賴注入本身也有一些麻煩,Pimple通過提供一個輕量級容器來以DRY的方式創(chuàng)建和存儲對象依賴項來解決這些問題。請隨時在下面的評論中分享您在項目中管理依賴項的經(jīng)驗,以及您對Pimple作為依賴注入容器的看法。

關(guān)于使用Pimple進(jìn)行依賴注入的常見問題解答 (FAQ)

什么是Pimple,為什么在PHP中使用它?

Pimple是一個簡單的PHP依賴注入容器,允許您管理和集中應(yīng)用程序中的服務(wù)。它用于PHP,使代碼更靈活、更可重用和更易于測試。通過使用Pimple,您可以在一個地方實(shí)例化對象,然后將它們注入到應(yīng)用程序的不同部分,從而減少對全局狀態(tài)的需求,并使您的代碼更易于維護(hù)和測試。

Pimple是如何工作的?

Pimple通過在容器中存儲服務(wù)定義來工作。這些定義是可以調(diào)用(函數(shù)或方法)的,它們返回服務(wù)的實(shí)例。當(dāng)您從容器訪問服務(wù)時,Pimple會執(zhí)行服務(wù)定義以創(chuàng)建服務(wù)對象。這允許您以集中方式管理服務(wù),并在整個應(yīng)用程序中共享服務(wù)。

如何安裝Pimple?

可以使用Composer(PHP的依賴項管理工具)安裝Pimple。您可以在系統(tǒng)上全局安裝Composer,然后通過運(yùn)行命令composer require pimple/pimple在項目中引入Pimple。

如何在Pimple中定義服務(wù)?

在Pimple中,您可以通過將可調(diào)用對象分配給容器中的鍵來定義服務(wù)。可調(diào)用對象應(yīng)返回服務(wù)的實(shí)例。例如,您可以像這樣為郵件發(fā)送器類定義服務(wù):

$container['mailer'] = function ($c) { return new Mailer($c['smtp']); };

在此示例中,郵件發(fā)送器服務(wù)定義為Mailer類的新的實(shí)例,其中smtp服務(wù)作為依賴項注入。

如何在Pimple中訪問服務(wù)?

您可以使用帶有服務(wù)鍵的數(shù)組表示法來訪問Pimple中的服務(wù)。例如,您可以像這樣訪問郵件發(fā)送器服務(wù):$mailer = $container['mailer'];。當(dāng)您訪問服務(wù)時,Pimple會執(zhí)行服務(wù)定義并返回服務(wù)對象。

如何在Pimple中共享服務(wù)?

默認(rèn)情況下,Pimple每次訪問服務(wù)時都會返回服務(wù)的新的實(shí)例。如果您想共享服務(wù)并每次返回相同的實(shí)例,可以使用share()方法。例如,您可以像這樣共享郵件發(fā)送器服務(wù):$container['mailer'] = $container->share(function ($c) { return new Mailer($c['smtp']); });

我可以在Pimple中擴(kuò)展服務(wù)嗎?

是的,您可以使用extend()方法擴(kuò)展Pimple中的服務(wù)。這允許您在定義服務(wù)后修改它。例如,您可以像這樣擴(kuò)展郵件發(fā)送器服務(wù)以添加其他配置:

$container['mailer'] = $container->extend('mailer', function ($mailer, $c) { $mailer->setFrom($c['email.from']); return $mailer; });

在此示例中,setFrom()方法使用email.from服務(wù)作為參數(shù)在郵件發(fā)送器服務(wù)上調(diào)用。

如何保護(hù)Pimple中的參數(shù)?

在Pimple中,您可以使用protect()方法保護(hù)參數(shù)(不應(yīng)被視為服務(wù)的參數(shù))。這允許您在容器中存儲值,而不會將它們視為服務(wù)定義。例如,您可以像這樣保護(hù)配置值:$container['config.value'] = $container->protect(function () { return 'value'; });

如何在一個項目中使用Pimple?

您可以通過創(chuàng)建PimpleContainer類的新的實(shí)例并在其中定義服務(wù)來在一個項目中使用Pimple。然后,您可以在應(yīng)用程序中需要的地方從容器訪問服務(wù)。這允許您以集中方式管理服務(wù)并將它們注入到應(yīng)用程序的不同部分。

使用Pimple的好處是什么?

Pimple為PHP開發(fā)提供了許多好處。它使您的代碼更靈活,因為它允許您以集中方式管理服務(wù)。它使您的代碼更易于重用,因為它允許您在整個應(yīng)用程序中共享服務(wù)。它使您的代碼更易于測試,因為它允許您注入模擬服務(wù)進(jìn)行測試。通過使用Pimple,您可以提高代碼質(zhì)量,并使其更易于維護(hù)和測試。

以上是PHP主|用丘疹注入依賴的詳細(xì)內(nèi)容。更多信息請關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本站聲明
本文內(nèi)容由網(wǎng)友自發(fā)貢獻(xiàn),版權(quán)歸原作者所有,本站不承擔(dān)相應(yīng)法律責(zé)任。如您發(fā)現(xiàn)有涉嫌抄襲侵權(quán)的內(nèi)容,請聯(lián)系admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費(fèi)脫衣服圖片

Undresser.AI Undress

Undresser.AI Undress

人工智能驅(qū)動的應(yīng)用程序,用于創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用于從照片中去除衣服的在線人工智能工具。

Clothoff.io

Clothoff.io

AI脫衣機(jī)

Video Face Swap

Video Face Swap

使用我們完全免費(fèi)的人工智能換臉工具輕松在任何視頻中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費(fèi)的代碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

功能強(qiáng)大的PHP集成開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級代碼編輯軟件(SublimeText3)

對基于PHP的API進(jìn)行版本控制的最佳實(shí)踐是什么? 對基于PHP的API進(jìn)行版本控制的最佳實(shí)踐是什么? Jun 14, 2025 am 12:27 AM

基于toversionaphp,useUrl deuseUrl specteringforclarityAndEsofRouting,單獨(dú)的codetoavoidConflicts,dremecateOldVersionswithClearCommunication,andConsiderCustomHeadeSerlySerallyWhennEnncelsy.startbyplacingtheversionIntheUrl(E.G.,epi/api/v

如何在PHP中實(shí)施身份驗證和授權(quán)? 如何在PHP中實(shí)施身份驗證和授權(quán)? Jun 20, 2025 am 01:03 AM

tosecurelyhandleauthenticationandationallizationInphp,lofterTheSesteps:1.AlwaysHashPasswordSwithPassword_hash()andverifyusingspasspassword_verify(),usepreparedStatatementStopreventsqlineptions,andStoreSeruserDatain usseruserDatain $ _sessiveferterlogin.2.implementrole-2.imaccessccsccccccccccccccccccccccccc.

PHP中有哪些弱參考(弱圖),何時有用? PHP中有哪些弱參考(弱圖),何時有用? Jun 14, 2025 am 12:25 AM

PHPdoesnothaveabuilt-inWeakMapbutoffersWeakReferenceforsimilarfunctionality.1.WeakReferenceallowsholdingreferenceswithoutpreventinggarbagecollection.2.Itisusefulforcaching,eventlisteners,andmetadatawithoutaffectingobjectlifecycles.3.YoucansimulateaWe

PHP中的程序和面向?qū)ο蟮木幊谭独g有什么區(qū)別? PHP中的程序和面向?qū)ο蟮木幊谭独g有什么區(qū)別? Jun 14, 2025 am 12:25 AM

procemal and object-tiriendedprogromming(oop)inphpdiffersimplessintustructure,可重復(fù)使用性和datahandling.1.procedural-Progrogursmingusesfunctimesfunctionsormanized sequalized sequalized sequiential,poiperforsmallscripts.2.OpporganizesCodeOrganizescodeOdeIntsocloceSandObjects,ModelingReal-Worlden-Worlden

如何在PHP中安全地處理文件上傳? 如何在PHP中安全地處理文件上傳? Jun 19, 2025 am 01:05 AM

要安全處理PHP中的文件上傳,核心在于驗證文件類型、重命名文件并限制權(quán)限。1.使用finfo_file()檢查真實(shí)MIME類型,僅允許特定類型如image/jpeg;2.用uniqid()生成隨機(jī)文件名,存儲至非Web根目錄;3.通過php.ini和HTML表單限制文件大小,設(shè)置目錄權(quán)限為0755;4.使用ClamAV掃描惡意軟件,增強(qiáng)安全性。這些步驟有效防止安全漏洞,確保文件上傳過程安全可靠。

PHP中==(松散比較)和===(嚴(yán)格的比較)之間有什么區(qū)別? PHP中==(松散比較)和===(嚴(yán)格的比較)之間有什么區(qū)別? Jun 19, 2025 am 01:07 AM

在PHP中,==與===的主要區(qū)別在于類型檢查的嚴(yán)格程度。==在比較前會進(jìn)行類型轉(zhuǎn)換,例如5=="5"返回true,而===要求值和類型都相同才會返回true,例如5==="5"返回false。使用場景上,===更安全應(yīng)優(yōu)先使用,==僅在需要類型轉(zhuǎn)換時使用。

如何與PHP的NOSQL數(shù)據(jù)庫(例如MongoDB,Redis)進(jìn)行交互? 如何與PHP的NOSQL數(shù)據(jù)庫(例如MongoDB,Redis)進(jìn)行交互? Jun 19, 2025 am 01:07 AM

是的,PHP可以通過特定擴(kuò)展或庫與MongoDB和Redis等NoSQL數(shù)據(jù)庫交互。首先,使用MongoDBPHP驅(qū)動(通過PECL或Composer安裝)創(chuàng)建客戶端實(shí)例并操作數(shù)據(jù)庫及集合,支持插入、查詢、聚合等操作;其次,使用Predis庫或phpredis擴(kuò)展連接Redis,執(zhí)行鍵值設(shè)置與獲取,推薦phpredis用于高性能場景,Predis則便于快速部署;兩者均適用于生產(chǎn)環(huán)境且文檔完善。

如何在PHP( - , *, /,%)中執(zhí)行算術(shù)操作? 如何在PHP( - , *, /,%)中執(zhí)行算術(shù)操作? Jun 19, 2025 pm 05:13 PM

PHP中使用基本數(shù)學(xué)運(yùn)算的方法如下:1.加法用 號,支持整數(shù)和浮點(diǎn)數(shù),也可用于變量,字符串?dāng)?shù)字會自動轉(zhuǎn)換但不推薦依賴;2.減法用-號,變量同理,類型轉(zhuǎn)換同樣適用;3.乘法用*號,適用于數(shù)字及類似字符串;4.除法用/號,需避免除以零,并注意結(jié)果可能是浮點(diǎn)數(shù);5.取模用%號,可用于判斷奇偶數(shù),處理負(fù)數(shù)時余數(shù)符號與被除數(shù)一致。正確使用這些運(yùn)算符的關(guān)鍵在于確保數(shù)據(jù)類型清晰并處理好邊界情況。

See all articles