Laravel: як створити користувацькі фасади

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();

 

Що погодьтеся, набагато простіше. Наостанок, як зазвичай, раджу ознайомитися з офіційною документацією, та їх тестуванню.

На цьому на сьогодні все. Успіхів!