Laravel фасады vs псевдонимы классов

Источник: «Laravel facades vs class aliases»
Есть разница между тем, что в Laravel называют фасадами и псевдонимами классов. Давайте рассмотрим, чем они отличаются друг от друга и как они стали так тесно переплетаться в глазах общественности.

Фасады

Фасад в 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\NumberNum для быстрого и удобного использования в представлениях.

Заключение

\Config — это не фасад, это псевдоним класса для фасада. Нет причин, по которым нельзя импортировать полное пространство имён в фасад в PHP-only файлах.

Я вообще считаю, что для фасадов нужно импортировать полное пространство имён (use Illuminate\Support\Facades\Config), а не псевдоним. Я также стараюсь ограничить использование псевдонимов классов в представлениях и предпочитаю использовать глобальные функции, предоставляемые Laravel, потому что псевдонимы не работают с автодополнением в моей IDE без внешнего инструментария.

Дополнительные материалы

Предыдущая Статья

Методы авторизации и валидации контроллеров в Laravel 11

Следующая Статья

Нет, типы TypeScript не существуют во время выполнения