Laravel фасады vs псевдонимы классов
Фасады
Фасад в Laravel — это не что иное, как прокси для объекта в сервис-контейнере. Другими словами, если объект привязан к сервис-контейнеру как my-service
, можно вызвать методы этого объекта с помощью статических методов следующего фасада:
namespace App\Facades;
use Illuminate\Support\Facades\Facade;
class MyServiceFacade extends Facade
{
public function getFacadeAccessor()
{
return 'my-service';
}
}
Обратите внимание на строку my-service
, с помощью которой сервис привязан к контейнеру. При вызове любого статического метода на этом фасаде вызывается магический метод фасада __callStatic()magic
, сервис my-service
извлекается из контейнера, и вызов перенаправляется на этот экземпляр.
Всё равно придётся ссылаться на полное пространство имён этого фасада (App\Facades\MyServiceFacade
), когда будете использовать его в своём приложении. По крайней мере, если не добавить псевдоним класса.
Псевдонимы классов
PHP позволяет разработчикам присваивать любому классу другое имя с помощью функции class_alias
. Например, если есть класс с именем Aang
, я могу присвоить ему псевдоним toBonzuPippinpaddleopsicopolisTheThird
и использовать его как обычный:
class Aang
{
public static function greet(): string
{
return 'Flameo!';
}
}
class_alias(Aang::class, 'BonzuPippinpaddleopsicopolisTheThird');
echo BonzuPippinpaddleopsicopolisTheThird::greet(); // Flameo!
При желании можно присвоить псевдоним другому пространству имён:
namespace App {
class User
{
public static function greet(): string
{
return 'Hello!';
}
}
}
namespace {
class_alias(App\User::class, 'User');
echo \User::greet(); // Hello!
}
Это может быть полезно при использовании классов с длинным FQCN в представлениях, где импорт классов с помощью операторов use
может быть невозможен или просто некрасив.
Наиболее очевидным недостатком является потеря автозавершения в большинстве IDE, поскольку IDE не может знать, когда/если функция class_alias()
была вызвана в данной точке вашего приложения.
Путаница
Laravel присваивает всем фасадам, с которыми он поставляется, имя базового класса, как во втором примере приведённом ранее. Это означает, что все классы в пространстве имён Illuminate\Support\Facades
доступны так же, как если бы они находились в глобальном пространстве имён. Это можно увидеть в файле config/app.php
(ключ aliases
).
Я думаю, что это поведение по умолчанию является причиной того, что многие люди в сообществе Laravel путают фасады и псевдонимы классов.
Использование класса с пространством имён так, как будто он живёт в глобальном пространстве имён, возможно не только для фасадов. В вышеупомянутом файле config/app.php
можно присвоить псевдонимы любым классам, которые захотите. Например, можно назвать Illuminate\Support\Str
просто Str
, а Illuminate\Support\Number
— Num
для быстрого и удобного использования в представлениях.
Заключение
\Config
— это не фасад, это псевдоним класса для фасада. Нет причин, по которым нельзя импортировать полное пространство имён в фасад в PHP-only файлах.
Я вообще считаю, что для фасадов нужно импортировать полное пространство имён (use Illuminate\Support\Facades\Config
), а не псевдоним. Я также стараюсь ограничить использование псевдонимов классов в представлениях и предпочитаю использовать глобальные функции, предоставляемые Laravel, потому что псевдонимы не работают с автодополнением в моей IDE без внешнего инструментария.