搜尋
首頁後端開發php教程yii2 隨筆(七)依賴注入-(4)服務定位器

服務定位器定位器是依賴注入的一種解決方式,它包含依賴注入,在解決了依賴注入後,如果服務使用者和服務提供者不是用一個人,那麼使用者要了解提供服務的必須參數,這樣才能確保依賴的正確性,這就耦合了使用者和提供者,服務定位器就是解耦這部分的,服務提供者在ServiceLocator 中註冊服務(同時註冊了依賴),僅僅告訴服務使用者那些服務的名稱或別名,那麼對於服務提供者和使用者都是好的,使用者只需要知道提供者提供的什麼服務,而不必知道依賴什麼,服務提供者也不必為使用者「胡亂使用」服務而導致的bug所困擾。

那麼yii2是怎麼使用ServiceLocator呢?其實很簡單如下

//魔术方法,
public function __get($name){
    //得到某个注册的方法
    if ($this->has($name)) {
        return $this->get($name);
    } else {
        return parent::__get($name);
    }
}
//魔术方法查看某个服务是否存在,源码略
public function __isset($name){}
//__isset()中调用,查看某个服务是否存在,源码略
public function has($id, $checkInstance = false){}
//得到某个服务
public function get($id, $throwException = true)
{
    if (isset($this->_components[$id])) {//如果是已经处理的服务,就直接返回
        return $this->_components[$id];
    }

    if (isset($this->_definitions[$id])) {//如定义了该服务
        $definition = $this->_definitions[$id];//得到服务的定义
        //如果服务是一个闭包,则把闭包注册到已经实例化的服务中,并且返回闭包
        if (is_object($definition) && !$definition instanceof Closure) {
            return $this->_components[$id] = $definition;
        } else {//其他的情况下通过依赖注入生成对象,并且注册为已处理,返回对象
            return $this->_components[$id] = Yii::createObject($definition);
        }
    } elseif ($throwException) {//如果抛出异常,则抛出异常
        throw new InvalidConfigException("Unknown component ID: $id");
    } else {//其他返回null
        return null;
    }
}
//注册一个服务
public function set($id, $definition)
{
    if ($definition === null) {//如果该服务的定义为null,则删除已经实例化的服务,返回空,用于注销已经实例化的并且保存过的服务的定义
        unset($this->_components[$id], $this->_definitions[$id]);
        return;
    }
    //清空已经实例化的服务
    unset($this->_components[$id]);
    //如果该服务的定义为一个对象,并且是一个可调用的结构
    if (is_object($definition) || is_callable($definition, true)) {
        // an object, a class name, or a PHP callable
        $this->_definitions[$id] = $definition;
    } elseif (is_array($definition)) {//如果该服务是一个配置数组
        // a configuration array
        if (isset($definition['class'])) {//如果有class键值,则直接注册为一个服务的定义
            $this->_definitions[$id] = $definition;
        } else {//是配置数组,但是没有指定class,则抛出异常
            throw new InvalidConfigException("The configuration for the \"$id\" component must contain a \"class\" element.");
        }
    } else {//什么都不是,抛出异常,非法注册服务
        throw new InvalidConfigException("Unexpected configuration type for the \"$id\" component: " . gettype($definition));
    }
}
//清空已经实例化过的服务和定义,代码略
public function clear($id){}
//得到已经实例化后的服务,或者得到可用的服务配置
public function getComponents($returnDefinitions = true){}
//注册所有的服务,这里的$components,就是你在config里写的 $config['components']值
public function setComponents($components){}

那麼ServiceLocator是從什麼時候介入的呢?我們繼續開我們的index.php,注意下面那句話

(new yii\web\Application($config))->run();

我們查看Application

class Application extends \yii\base\Application
//继续追踪  \yii\base\Application
abstract class Application extends Module
//继续追踪  Module
class Module extends ServiceLocator
哈,終於找到丫了! ! !我們的application 其實就一個服務定位器,我們在設定檔裡設定的components,都是application的這個服務定位器註冊的服務。這下知道為什麼叫做 setComponents這個函數了吧,不明白繼續往下看。

yii 用 set[typename] 的函式來確保屬性的可寫性,在基底類別 yiibaseObject 的建構子裡使用了 Yii::configure($this, $config);這個會呼叫 setComponents 函式註冊服務。

好啦,前後都聯繫上了,yii2使用的依賴注入和服務定位器,就說到這裡。

以上就是yii2 隨筆(七)依賴注入-(4)服務定位器的內容,更多相關內容請關注PHP中文網(www.php.cn)!


陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
PHP如何識別用戶的會話?PHP如何識別用戶的會話?May 01, 2025 am 12:23 AM

phpIdentifiesauser'ssessionSessionSessionCookiesAndSessionId.1)whiwsession_start()被稱為,phpgeneratesainiquesesesessionIdStoredInacookInAcookInAcienamedInAcienamedphpsessIdontheuser'sbrowser'sbrowser.2)thisIdallowSphptpptpptpptpptpptpptpptoretoreteretrieetrieetrieetrieetrieetrieetreetrieetrieetrieetrieetremthafromtheserver。

確保PHP會議的一些最佳實踐是什麼?確保PHP會議的一些最佳實踐是什麼?May 01, 2025 am 12:22 AM

PHP會話的安全可以通過以下措施實現:1.使用session_regenerate_id()在用戶登錄或重要操作時重新生成會話ID。 2.通過HTTPS協議加密傳輸會話ID。 3.使用session_save_path()指定安全目錄存儲會話數據,並正確設置權限。

PHP會話文件默認存儲在哪裡?PHP會話文件默認存儲在哪裡?May 01, 2025 am 12:15 AM

phpsessionFilesArestoredIntheDirectorySpecifiedBysession.save_path,通常是/tmponunix-likesystemsorc:\ windows \ windows \ temponwindows.tocustomizethis:tocustomizEthis:1)useession_save_save_save_path_path()

您如何從PHP會話中檢索數據?您如何從PHP會話中檢索數據?May 01, 2025 am 12:11 AM

ToretrievedatafromaPHPsession,startthesessionwithsession_start()andaccessvariablesinthe$_SESSIONarray.Forexample:1)Startthesession:session_start().2)Retrievedata:$username=$_SESSION['username'];echo"Welcome,".$username;.Sessionsareserver-si

您如何使用會議來實施購物車?您如何使用會議來實施購物車?May 01, 2025 am 12:10 AM

利用會話構建高效購物車系統的步驟包括:1)理解會話的定義與作用,會話是服務器端的存儲機制,用於跨請求維護用戶狀態;2)實現基本的會話管理,如添加商品到購物車;3)擴展到高級用法,支持商品數量管理和刪除;4)優化性能和安全性,通過持久化會話數據和使用安全的會話標識符。

您如何在PHP中創建和使用接口?您如何在PHP中創建和使用接口?Apr 30, 2025 pm 03:40 PM

本文解釋瞭如何創建,實施和使用PHP中的接口,重點關注其對代碼組織和可維護性的好處。

crypt()和password_hash()有什麼區別?crypt()和password_hash()有什麼區別?Apr 30, 2025 pm 03:39 PM

本文討論了PHP中的crypt()和password_hash()的差異,以進行密碼哈希,重點介紹其實施,安全性和對現代Web應用程序的適用性。

如何防止PHP中的跨站點腳本(XSS)?如何防止PHP中的跨站點腳本(XSS)?Apr 30, 2025 pm 03:38 PM

文章討論了通過輸入驗證,輸出編碼以及使用OWASP ESAPI和HTML淨化器之類的工具來防止PHP中的跨站點腳本(XSS)。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具