
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();
Что согласитесь, гораздо проще. Напоследок, как обычно, настоятельно советую ознакомиться с официальной документацией по фасадам, и их тестированию.
На этом на сегодня всё. Успехов!