Facades và mối quan hệ giữa Facades với Service Container trong Laravel
Tìm hiểu về Facade trong Laravel Static method Các thuộc tính, phương thức trong lớp khai báo với từ khóa static là một đặc tính hữu dụng trong PHP. Về cơ bản, phương thức / thuộc tính tĩnh (static) thì nó có thể truy cập trực tiếp mà không phải tạo đối tượng của lớp. Ví dụ về static ...
Tìm hiểu về Facade trong Laravel
-
Static method
Các thuộc tính, phương thức trong lớp khai báo với từ khóa static là một đặc tính hữu dụng trong PHP. Về cơ bản, phương thức / thuộc tính tĩnh (static) thì nó có thể truy cập trực tiếp mà không phải tạo đối tượng của lớp. Ví dụ về static method và non-static method.
class Math { private $firstNumber; public function __construct(int $firstNumber) { $this->firstNumber = $firstNumber; } public function add(int $secondNumber) { return $sum = $this->firstNumber + $secondNumber; } public static function mul(int $firstNumber, int $secondNumber) { return $firstNumber * $secondNumber; } } $math = new Math(10); $addResult = $math->add(5); //15 $mulResult = Math::mul(10,5); //50
-
Magic methods
Trong quá trình code, chúng ta sử dụng rất nhiều lần các phương thức như __construct(), __call(),… Các phương thức này chính là magic method. Vậy magic method là các phương thức đặc biệt để tùy biến các các sự kiện trong php. Có thể hiểu đơn giản là nó cung cấp thêm cách để giải quyết một vấn đề nào đó trong phạm vi class. Magic method được dùng để xử lý các đối tượng trong lập trình hướng đối tượng, dưới đây là ví dụ về 2 magic methods thường dùng
class Math { private $firstNumber; public function __construct(int $firstNumber) { $this->firstNumber = $firstNumber; } public function __destruct() { echo 'this Object has been destroyed'; } }
Trước khi tìm hiểu rõ hơn về Facade, ta hãy tìm hiểu trước về magic method là __callStatic(). Khi gọi đến một static method chưa được khai báo bị lỗi “Call to undefined method”, nhưng nếu ta đã có phương thức __callStatic() trong class, PHP sẽ tự động gọi tới đó (__callStatic() chỉ có áp dụng với các static method), tương tự __call() chỉ áp dụng được với các non-static method.
class Math { private $firstNumber; public function __construct(int $firstNumber) { $this->firstNumber = $firstNumber; } public function __destruct() { echo 'this Object has been destroyed'; } public static function __callStatic($name, $arguments) { echo "Undefined static method called"; } } Math::undefinedMethod(); //Undefined static method called
-
Facades
Facades là một trong những tính năng rất hữu dụng trong laravel với Facades, chúng ta có thể truy cập đến hầu hết các tính năng của laravel Ví dụ về sử dụng facades: Auth::id(), Auth::user(), Route::get(),… Để hiểu rõ hơn, hãy vào xem file config/app.php
'aliases' => [ 'App' => IlluminateSupportFacadesApp::class, 'Artisan' => IlluminateSupportFacadesArtisan::class, 'Auth' => IlluminateSupportFacadesAuth::class, 'Blade' => IlluminateSupportFacadesBlade::class, 'Broadcast' => IlluminateSupportFacadesBroadcast::class, 'Bus' => IlluminateSupportFacadesBus::class, 'Cache' => IlluminateSupportFacadesCache::class, 'Config' => IlluminateSupportFacadesConfig::class, 'Cookie' => IlluminateSupportFacadesCookie::class, 'Crypt' => IlluminateSupportFacadesCrypt::class, 'DB' => IlluminateSupportFacadesDB::class, 'Eloquent' => IlluminateDatabaseEloquentModel::class, 'Event' => IlluminateSupportFacadesEvent::class, 'File' => IlluminateSupportFacadesFile::class, 'Gate' => IlluminateSupportFacadesGate::class, 'Hash' => IlluminateSupportFacadesHash::class, 'Lang' => IlluminateSupportFacadesLang::class, 'Log' => IlluminateSupportFacadesLog::class, 'Mail' => IlluminateSupportFacadesMail::class, 'Notification' => IlluminateSupportFacadesNotification::class, 'Password' => IlluminateSupportFacadesPassword::class, 'Queue' => IlluminateSupportFacadesQueue::class, 'Redirect' => IlluminateSupportFacadesRedirect::class, 'Redis' => IlluminateSupportFacadesRedis::class, 'Request' => IlluminateSupportFacadesRequest::class, 'Response' => IlluminateSupportFacadesResponse::class, 'Route' => IlluminateSupportFacadesRoute::class, 'Schema' => IlluminateSupportFacadesSchema::class, 'Session' => IlluminateSupportFacadesSession::class, 'Storage' => IlluminateSupportFacadesStorage::class, 'URL' => IlluminateSupportFacadesURL::class, 'Validator' => IlluminateSupportFacadesValidator::class, 'View' => IlluminateSupportFacadesView::class, ],
Tại đây, rất nhiều cái tên quen thuộc như App, DB, Auth,… Laravel đã khai báo sẵn một loạt các class alias. Mục đích của việc này để chúng ta có thể sử dụng khi code với cái tên ngắn gọn thay vì phải viết đầy đủ cả namespace. Ví dụ khai báo ‘Auth’ => IlluminateSupportFacadesAuth::class, khi chúng ta sử dụng class Auth, thực tế ta đã gọi đến class IlluminateSupportFacadesAuth. Để ý chút ta sẽ thấy tên các class được đăng ký alias đều có namespace chung là IlluminateSupportFacades.Điều này có nghĩa là những class được đăng ký ở đây đều là Facades, và tất cả những class này đều extends một class có tên là Facade. Từ ví dụ các facades Auth::id(), Auth::user(), Auth::logout(),… Các gọi này chính là gọi các static method, hãy xem trong class Auth ta có những method nào.
class Auth extends Facade { /** * Get the registered name of the component. * * @return string */ protected static function getFacadeAccessor() { return 'auth'; } /** * Register the typical authentication routes for an application. * * @return void */ public static function routes() { static::$app->make('router')->auth(); } }
Có thể thấy trong class Auth không có static method nào là id(), user(),… cả, nhưng ta thấy class này overrides lại một hàm là getFacadeAccessor(), hãy vào thử abstact class Facade xem nó có gì bên trong.
protected static function getFacadeAccessor() { return 'auth'; }
Việc định nghĩa hàm getFacadeAccessor() sẽ bắt buộc các class extends từ class Facade sẽ phải overrides lại hàm này, nếu không sẽ throw ra Exception.
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); }
Kéo xuống phần dưới cùng của class, ta thấy có magic method là __callStatic(). Như đã trình bày ở trên, khi gọi các hàm static của Auth thực tế sẽ được xử lý trong magic method __callStatic, ở đây sẽ tạo ra một Facade instance, instance này được resolve ra từ Application Instance $$pp với hàm getFacadeRoot(); (Chính là Service Container). Như vậy việc sử dụng facade Auth chính là sử dụng service auth của Service Container Ví dụ:
Auth::user(); // Tương đương với $auth = app(‘auth’); $auth->user();
Bài viết này hy vọng sẽ giúp bạn hiểu rõ hơn về Facades, cũng như sự ứng dụng của Service Container trong Laravel. Dưới đây là tên các Facade với Class và Service Container tương ứng.
Facade | Class | Service Container Binding |
---|---|---|
App | IlluminateFoundationApplication | app |
Artisan | IlluminateContractsConsoleKernel | artisan |
Auth | IlluminateAuthAuthManager | auth |
Auth (Instance) | IlluminateContractsAuthGuard | auth.driver |
Blade | IlluminateViewCompilersBladeCompiler | blade.compiler |
Broadcast | IlluminateContractsBroadcastingFactory | |
Broadcast (Instance) | IlluminateContractsBroadcastingBroadcaster | |
Bus | IlluminateContractsBusDispatcher | |
Cache | IlluminateCacheCacheManager | cache |
Cache | (Instance) IlluminateCacheRepository | cache.store |
Config | IlluminateConfigRepository | config |
Cookie | IlluminateCookieCookieJar | cookie |
Crypt | IlluminateEncryptionEncrypter | encrypter |
DB | IlluminateDatabaseDatabaseManager | db |
DB | (Instance) | IlluminateDatabaseConnection |
Event | IlluminateEventsDispatcher | events |
File | IlluminateFilesystemFilesystem | files |
Gate | IlluminateContractsAuthAccessGate | |
Hash | IlluminateContractsHashingHasher | hash |
Lang | IlluminateTranslationTranslator | translator |
Log | IlluminateLogLogger | log |
IlluminateMailMailer | mailer | |
Notification | IlluminateNotificationsChannelManager | |
Password | IlluminateAuthPasswordsPasswordBrokerManager | auth.password |
Password | (Instance) IlluminateAuthPasswordsPasswordBroker | auth.password.broker |
Queue | IlluminateQueueQueueManager | queue |
Queue | (Instance)IlluminateContractsQueueQueue | queue.connection |
Queue | (Base Class) IlluminateQueueQueue | |
Redirect | IlluminateRoutingRedirector | redirect |
Redis | IlluminateRedisRedisManager | redis |
Redis (Instance) | IlluminateRedisConnectionsConnection | redis.connection |
Request | IlluminateHttpRequest | request |
Response | IlluminateContractsRoutingResponseFactory | |
Response (Instance) | IlluminateHttpResponse | |
Route | IlluminateRoutingRouter | router |
Schema | IlluminateDatabaseSchemaBuilder | |
Session | IlluminateSessionSessionManager | session |
Session | (Instance) IlluminateSessionStore | session.store |
Storage | IlluminateFilesystemFilesystemManager | filesystem |
Storage | (Instance) IlluminateContractsFilesystemFilesystem | filesystem.disk |
URL | IlluminateRoutingUrlGenerator | url |
Validator | IlluminateValidationFactory | validator |
Validator (Instance) | IlluminateValidationValidator | |
View | IlluminateViewFactory | view |
View (Instance) | IlluminateViewView |
Bài viết tham khảo từ nhiều nguồn