
Laravel: як створити користувацькі фасади
22.03.2021 23:36 | Laravel
OS: Ubuntu 20.04.2 LTS
PHP: 8.0.0
Laravel: 8.33.1
Ми часто стикаємося з різними фасадами "з коробки", такими як DB
, Cache
, Validator
и т.д. (повний список можна знайти тут), але що робити, якщо нам в силу тих чи інших обставин треба створити фасад для свого класу?
Припустимо, у нас є клас ProductService
, який ми розмістили у директорії app/Services
. Щоб не ускладнювати приклад, візьмемо що-небудь елементарне:
<?php
namespace App\Services;
class ProductService
{
public function popularProducts()
{
return 'List of the most popular products';
}
}
Щоб не засмічувати AppServiceProvider
, створимо провайдер для фасадів:
php artisan make:provider FacadeServiceProvider
та привʼяжемо реалізацію до аліасу, тобто в підсумку клас провайдера буде виглядати так:
<?php
namespace App\Providers;
use App\Services\ProductService;
use Illuminate\Support\ServiceProvider;
class FacadeServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->bind('product.service', fn () => new ProductService());
}
}
Зареєструємо провайдер у config/app.php
:
'providers' => [
...
/*
* Application Service Providers...
*/
...
App\Providers\FacadeServiceProvider::class,
],
Далі створюємо безпосередньо сам клас фасаду, який покладемо у теку для фасадів app/Facades
:
<?php
namespace App\Facades;
use Illuminate\Support\Facades\Facade;
class ProductServiceFacade extends Facade
{
protected static function getFacadeAccessor()
{
return 'product.service';
}
}
Готово. Тепер в будь-якій частині додатка зробивши наступний виклик:
...
use App\Facades\ProductServiceFacade;
...
ProductServiceFacade::popularProducts();
...отримаємо рядок "List of the most popular products". Слід зазначити, що можна було б також додати і псевдонім для фасаду в config/app.php
, у секцію аліасів, але можна обійтися і без цього.
Здавалося б, на цьому можна ставити крапку, але є ще одна фішка - real-time фасади. Припустимо, у нас є CustomerService
:
<?php
namespace App\Services;
class CustomerService
{
public function customersList()
{
return 'Customers list';
}
}
Все, що потрібно для генерації фасаду в реальному часі - додати префікс перед неймспейсом класу в директиві use
, тобто:
...
use Facades\App\Services\CustomerService;
...
CustomerService::customersList();
Що погодьтеся, набагато простіше. Наостанок, як зазвичай, раджу ознайомитися з офіційною документацією, та їх тестуванню.
На цьому на сьогодні все. Успіхів!