この記事では主に Laravel のファサード外観システムの分析を紹介します。これには一定の参考値があります。今、あなたに共有します。困っている友達は参考にしてください。
今日は Laravel のコア アーキテクチャについて学びます. もうひとつのテーマ「ファサード」。
この記事では、Laravel の Facade の動作原理を包括的に説明するために、次の側面から開始します。
- 「外観」デザイン パターンの簡単な紹介;
- Laravel の読み込み原理」外観";
- Laravelの基本的な使い方「外観」。
- 「外観」デザイン パターンとは
外観パターン定義
サブシステム内の一連のインターフェイスに統一されたエントリを提供します。ファサード パターンは、このサブシステムを使いやすくする高レベルのインターフェイスを定義します。
外観パターンは、非常に頻繁に使用される構造設計パターンです。外観の役割を導入することで、クライアントとサブシステム間の対話を簡素化します。
複雑なサブシステム呼び出しを提供します。統一された入口により、クライアント間の結合が軽減されます。サブシステムとクライアント、およびクライアント呼び出しは非常に便利です。 - デザインパターン Java EditionCore
は、クライアント (ユーザー) と サブシステム (インターフェースまたはサービス) 「外観」の間のリンクを導入することです。キャラクター。 ユーザーとサブシステム間の直接的な結合を、「外観」クラスによってユーザーに提供される統一インターフェイスに変換して、クライアントとサブシステム間の結合を軽減します。
構造図:
## 「外観モード」については、デザインパターン Java Edition - 外観モード
を参照してください。
Laravel の「外観」コンポーネントは、実際にはサービス コンテナ内の基礎となるクラスの「静的プロキシ」であり、Laravel コアで定義された「コントラクト」(サービス、コントラクト、または通常のものとも呼ばれます) を使用します。これは、静的かつ呼び出し可能な方法で各「外観」サービスにカプセル化されており、使用することができます。
外観読み込みの原則
すべての組み込みの外観コンポーネントの設定データは、他の Laravel サービスと同様に、
ファイルで定義されます。
aliases ノードの構成データを見てみましょう: ...
'aliases' => [
'App' => Illuminate\Support\Facades\App::class,
'Artisan' => Illuminate\Support\Facades\Artisan::class,
...
],
...
外観構成定義の形式は、"Alias":"Appearance Class" のデータ形式に従います。 。 HTTP リクエストが受信されると、これらの「ルック アンド フィール」コンポーネントがリクエスト処理フェーズ中にサービスにロードされます。
次に、外観サービスの読み込みプロセスを詳細に分析します。 外観サービスの読み込み
「外観」サービスの読み込み作業は、
Illuminate\Foundation\Http\Kernelカーネル
\Illuminate\Foundation\ で定義されています。 Bootstrap \RegisterFacades::classランチャーが完了します。 ブート スタート アピアランス サービスLaravel サービス プロバイダーの実装原則の詳細な分析に関する私の別の記事を読んでいるなら、ブートストラップ プログラムについてあまり詳しくないはずです。
ブートストラップは、HTTP リクエストを処理した後、ブートの起動
bootstrap()を完了します。したがって、ここでは、より詳細な処理を理解するために、
RegisterFacades クラスを深く掘り下げる必要があります。 <?php
namespace Illuminate\Foundation\Bootstrap;
use Illuminate\Foundation\AliasLoader;
use Illuminate\Support\Facades\Facade;
use Illuminate\Foundation\PackageManifest;
use Illuminate\Contracts\Foundation\Application;
/**
* @link https://github.com/laravel/framework/blob/56a58e0fa3d845bb992d7c64ac9bb6d0c24b745a/src/Illuminate/Foundation/Bootstrap/RegisterFacades.php
*/
class RegisterFacades
{
/**
* Bootstrap the given application. 引导启动服务
*/
public function bootstrap(Application $app)
{
// 清除已解析的「外观」服务实例
Facade::clearResolvedInstances();
// 将 Laravel 服务容器注入到「外观」服务
Facade::setFacadeApplication($app);
// 加载所有外观服务
AliasLoader::getInstance(array_merge(
$app->make('config')->get('app.aliases', []),
$app->make(PackageManifest::class)->aliases()
))->register();
}
}
外観サービスのロードには AliasLoader コンポーネントの補完があります:
まず、構成ファイル
config/app からロードされます。 .php- すべての「外観」サービス構成を読み取ります
- aliases
;次に、マニフェスト ファイルからエイリアス サービスを読み取ります
$app->make (PackageManifest ::class)->aliases() ; -
2 つの構成配列を結合し、
AliasLoader に挿入します。 - 登録を完了します (登録する) ###。
外観サービスの登録
最後に、 AliasLoader
<?php
namespace Illuminate\Foundation;
/**
* @link https://github.com/laravel/framework/blob/56a58e0fa3d845bb992d7c64ac9bb6d0c24b745a/src/Illuminate/Foundation/AliasLoader.php
*/
class AliasLoader
{
/**
* Get or create the singleton alias loader instance. 获取或创建「别名加载器」单例实例。
*/
public static function getInstance(array $aliases = [])
{
if (is_null(static::$instance)) {
return static::$instance = new static($aliases);
}
$aliases = array_merge(static::$instance->getAliases(), $aliases);
static::$instance->setAliases($aliases);
return static::$instance;
}
/**
* Set the registered aliases. 设置需注册别名数据。
*/
public function setAliases(array $aliases)
{
$this->aliases = $aliases;
}
/**
* Register the loader on the auto-loader stack. 将加载器注册到自动加载中。
*/
public function register()
{
if (! $this->registered) {
$this->prependToLoaderStack();
$this->registered = true;
}
}
/**
* Prepend the load method to the auto-loader stack. 设置自动加载方法。
*/
protected function prependToLoaderStack()
{
// 将 AliasLoader 的 load 方法作为 __autoload 的实现
spl_autoload_register([$this, 'load'], true, true);
}
/**
* Load a class alias if it is registered.从注册过的服务中加载这个「外观」服务。
*/
public function load($alias)
{
if (static::$facadeNamespace && strpos($alias, static::$facadeNamespace) === 0) {
$this->loadFacade($alias);
return true;
}
if (isset($this->aliases[$alias])) {
return class_alias($this->aliases[$alias], $alias);
}
}
}
Note ここは知識ポイントです。AliasLoader->register()
で「外部サービスの登録」を完了するには、次の 2 つの PHP 知識を適用する必要があります:PHP 組み込みマジック メソッドの使用法 __autoload
;PHP でクラスのエイリアスを作成する方法。
- ➤ 1. 外観サービスの動的導入 __autoload
更优的解决方案是通过 spl_autoload_register 函数,将自定义的类加载程序作为 __autoload 的实现,以替代默认 __autoload() 模式函数或方法的行为。
所有 prependToLoaderStack() 方法:
/** * Prepend the load method to the auto-loader stack. 设置自动加载方法。 */ protected function prependToLoaderStack() { // 将 AliasLoader 的 load 方法作为 __autoload 的实现 spl_autoload_register([$this, 'load'], true, true); }
就是去完成这样的作用,将 AliasLoader->load() 方法作为自动加载程序的实现,在使用「外观」服务时动态引入这个类。
➤ 2. 支持外观服务别名
我们已经了解到当「外观」服务被使用时,由 AliasLoader->load() 去自动加载这个类。
与此同时,load 方法通过 class_alias($original, $alias) 函数完成别名注册。
这样,当我们使用 App 类时实际上就是在使用 Illuminate\Support\Facades\App 类。
很完美么,我们的「狗蛋」终于与「世界上最好的语言」画上了等号。你就是我,我就是你。
到这里其实已经完成了「外观」服务工作原理分析工作的 70%。
探秘 Facade
最后我们将揭开 Facade 的神秘面纱,研究一下 Laravel 是如何实现 Facade 设计模式的。
我们拿 IlluminateSupportFacadesApp 外观服务开刀,去解开类似 App::make() 静态方法使用的奥秘。
深入 FacadesApp:
<?php namespace Illuminate\Support\Facades; class App extends Facade { /** * Get the registered name of the component. */ protected static function getFacadeAccessor() { return 'app'; } }
我们看到它的实现内部仅仅定义了一个 getFacadeAccessor 方法,该方法的功能是获取已注册组件的名称 app;除此之外,一无所有。
看来在这里我们得不到什么有用的信息了。继续调查基类 IlluminateSupportFacadesFacade。如果你有去通便浏览全部的源码。
<?php namespace Illuminate\Support\Facades; use Mockery; use RuntimeException; use Mockery\MockInterface; /** * @link https://github.com/laravel/framework/blob/5.6/src/Illuminate/Support/Facades/Facade.php */ abstract class Facade { /** * Handle dynamic, static calls to the object. */ public static function __callStatic($method, $args) { $instance = static::getFacadeRoot(); if (! $instance) { throw new RuntimeException('A facade root has not been set.'); } return $instance->$method(...$args); } }
你会发现这个 Facade 基类并没有定义类似 make 的方法,那么这里能够静态调用 App::make() 看来是需要从 __callStatic 着手才行。
不过在这里我们需要再次厘清一个事实:「外观」模式的功能是什么?
将使用者与子系统从直接耦合,转变成由「外观」类提供统一的接口给使用者使用,以降低客户端与子系统之间的耦合度。
这句话的意思就是我「外观」啥也不提供,就是一层对服务(或者说组件或接口)的封装,然后以统一的方式提供给你们外部调用。
好了现在我们来看看 Facade::__callStatic 是如何获取实际的服务并调用响应的方法的吧。
首先,通过 getFacadeRoot 静态方法获取实际服务的实例对象;
然后,调用实例对象的相关方法并返回处理结果。
<?php namespace Illuminate\Support\Facades; use Mockery; use RuntimeException; use Mockery\MockInterface; abstract class Facade { /** * Get the root object behind the facade. 从 facade 中解析出真实服务的对象 */ public static function getFacadeRoot() { return static::resolveFacadeInstance(static::getFacadeAccessor()); } /** * Resolve the facade root instance from the container.me 从 Laravel 服务容器中解析出真实服务的对象 */ 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]; } }
从 getFacadeRoot 解析对象的功能中我们可以看到:它会调用实现「外观」的 getFacadeAccessor 方法获取到组件(服务或者说接口)的名称;然后从 Laravel 服务容器 static::$app[$name](app 是在 RegisterFacades 中注册到「外观」中) 中解析出相关服务。
到这里,我们就将「外观」服务的基本工作原理给分析透彻了。
另外有关「外观」组件的一些细枝末节,如:
在文档「Facades Vs. 辅助函数」一节提到的测试验证是如何实现的 Cache::shouldReceive('get');
什么是「实时 Facades」。
还是需要你自行深入到 Facade 基类去一探究竟。
扫盲 ArrayAccess 接口
另外补充一个知识点就是关于 static::$app[$name] 这一句代码。你不经要问,这有啥好补充的呢,不就是一个简单获取数据么。
获取数据不假,简单也不假。
不过你仔细看一下,你会发现 static::$app 静态成员变量难道不是一个 \Illuminate\Contracts\Foundation\Application 实现实例么,怎么可以从对象中以数组的方式获取值呢?
这是因为我们的服务容器 Illuminate\Container\Container 实现了 ArrayAccess 接口。
该接口的功能是提供像访问数组一样访问对象的能力的接口,这样就可以像数组一样访问对象访问成员。
/** *@link https://github.com/laravel/framework/blob/5.6/src/Illuminate/Container/Container.php */ class Container implements ArrayAccess, ContainerContract { /** * Get the value at a given offset. 获取一个偏移位置的值,实际上从容器中解析出服务。 */ public function offsetGet($key) { return $this->make($key); } }
Laravel「外观」基本使用
外观服务的一个典型使用场景是在定义路由时使用 Route::get('/', ...)。这样一看似乎「Laravel 别名服务」也就不这么神秘了。
上記がこの記事の全内容です。皆様の学習に役立つことを願っています。その他の関連コンテンツについては、PHP 中国語 Web サイトに注目してください。
関連する推奨事項:
#Laravel サービス プロバイダー (ServiceProvider) の解釈
以上がLaravelのファサード外観システムの分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

phpidentifiesauser'ssessionsingsinssessionCookiesIds.1)whensession_start()iscalled、phpgeneratesauniquesidstoredsored incoookienadphpsessidontheuser'sbrowser.2)thisidallowsphptortorieSessiondatadata fromthata

PHPセッションのセキュリティは、次の測定を通じて達成できます。1。session_regenerate_id()を使用して、ユーザーがログインまたは重要な操作である場合にセッションIDを再生します。 2. HTTPSプロトコルを介して送信セッションIDを暗号化します。 3。Session_Save_Path()を使用して、セッションデータを保存し、権限を正しく設定するためのSecure Directoryを指定します。

phpsessionFilesToredInthededirectoryspecifiedBysession.save_path、通常/tmponunix-likesystemsorc:\ windows \ temponwindows.tocustomizethis:1)uesession_save_path()tosetaCustomdirectory、ensuringit'swritadistradistradistradistradistra

toretrievedatafrompsession、Startthessession withsession_start()andAccessvariablesshe $ _SessionArray.forexample:1)Startthessession:session_start()

セッションを使用して効率的なショッピングカートシステムを構築する手順には、次のものがあります。1)セッションの定義と機能を理解します。セッションは、リクエスト全体でユーザーのステータスを維持するために使用されるサーバー側のストレージメカニズムです。 2)ショッピングカートに製品を追加するなど、基本的なセッション管理を実装します。 3)製品の量管理と削除をサポートし、高度な使用状況に拡大します。 4)セッションデータを持続し、安全なセッション識別子を使用することにより、パフォーマンスとセキュリティを最適化します。

この記事では、PHPでインターフェイスを作成、実装、および使用する方法について説明し、コード組織と保守性の利点に焦点を当てています。

この記事では、PHPのCrypt()とpassword_hash()の違いについて、パスワードハッシュの違いについて説明し、最新のWebアプリケーションの実装、セキュリティ、および適合性に焦点を当てています。

記事では、入力検証、出力エンコード、およびOWASP ESAPIやHTML浄化器などのツールを使用して、PHPのクロスサイトスクリプト(XSS)を防止します。


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ドリームウィーバー CS6
ビジュアル Web 開発ツール

メモ帳++7.3.1
使いやすく無料のコードエディター

AtomエディタMac版ダウンロード
最も人気のあるオープンソースエディター

VSCode Windows 64 ビットのダウンロード
Microsoft によって発売された無料で強力な IDE エディター

ホットトピック









