今天柚子深入學習了Laravel的外觀模式,這節讓我們帶着問題去學習Slim的外觀模式。
問題1.外觀模式爲何可以快速指定到類?
問題2.Slim如何集成外觀模式?
問題1
外觀模式大量使用PHP的後期靜態綁定即父類定義的屬性子類可以直接使用。外觀模式Facade抽象類的__callStatic魔術方法是關鍵。
問題2
實現Slim的外觀模式,使用Facade做服務容器內基類的靜態代理。使用各種服務基類會更加方便易用。譬如:Cache::get($name)方法,若查看Cache類會發現,類中並不存在get()靜態方法,實質是從依賴注入容器中獲取了cache服務基類$instance = $app->get(‘cache’)之後,執行了$instance->get($name);
Slim要想實現外觀模式,必須考慮兩個問題
1.外觀模式核心類及服務容器的外觀模式類的加載位置(可手寫php加載器,這裏推薦使用Composer)
2.在應用主體$app的整個生命週期中,應該在各類服務已經注入到容器之後及路由執行之前,將$app賦值給Facade基類的$app方法。(這裏Facache的$app屬性賦值採用後期靜態綁定方式)
Slim本身不具備外觀模式。但我們可以重寫Facade類,實現專屬於Slim的外觀模式。
第一步,編輯composer.json,將App命名空間與app目錄映射。
{
"require": {
"slim/slim": "^3.9",
"monolog/monolog": "^1.23",
"illuminate/database": "~5.1",
"slim/twig-view": "^2.3"
},
"autoload": {
"psr-4": {
"App\\": "app/"
}
}
}
第二步,建立app目錄結構
第三步,新建Facade類,該類重寫了\Illuminate\Support\Facades\Facade類。<?php
namespace App\Facade;
class Facade extends \Illuminate\Support\Facades\Facade
{
/**
* 重寫\Illuminate\Support\Facades\Facade該方法
* @param object|string $name
* @return object|string
*/
protected static function resolveFacadeInstance($name)
{
if (is_object($name)) {
return $name;
}
if (isset(static::$resolvedInstance[$name])) {
return static::$resolvedInstance[$name];
}
//return static::$resolvedInstance[$name] = static::$app[$name];
return static::$resolvedInstance[$name] = static::$app->getContainer()->$name;
}
}
第四步,實現一個LogFacade.php,並使用該外觀類。
<?php
namespace App\Facade;
class LogFacade extends Facade
{
public static function getFacadeAccessor()
{
return "logger";
}
}
第五步,加載外觀模式並使用該模式。
// 外觀模式加載
\Illuminate\Support\Facades\Facade::clearResolvedInstances();
\Illuminate\Support\Facades\Facade::setFacadeApplication($app);
$app->get('/facade', function () {
\App\Facade\LogFacade::addInfo('haha');
});