Может войдёшь?
Черновики Написать статью Профиль

Фасады

перевод документация 4.x

  1. 1. Введение
  2. 2. Описание
  3. 3. Практическое использование
  4. 4. Создание фасадов
  5. 5. Об автозагрузке псевдонимов
  6. 6. Фасады-заглушки
  7. 7. Соответствие фасадов и классов
Этот перевод актуален для англоязычной документации на (ветка 4.2) , (ветка 4.1) и (ветка 4.0). Опечатка? Выдели и нажми Ctrl+Enter.

Введение

Фасады предоставляют «статический» интерфейс к классам, доступным в контейнере IoC. Laravel поставляется со множеством фасадов и вы, вероятно, использовали их, даже не подозревая об этом. «Фасады» Laravel служат «статическими прокси» для классов в IoC-контейнере, обеспечивая преимущества краткого выразительного синтаксиса, и поддерживая большую тестируемость и гибкость, чем традиционные статические методы.

Иногда вам может понадобиться создать собственные фасады для вашего приложения и пакетов, поэтому давайте изучим идею, разработку и использование этих классов.

Внимание: перед погружением в фасады настоятельно рекомендуется как можно детальнее изучить контейнер IoC.

Описание

В контексте приложения на Laravel, фасад — это класс, который предоставляет доступ к объекту в контейнере. Весь этот механизм реализован в классе PHPFacade. Фасады как Laravel, так и ваши собственные, наследуют этот базовый класс.

Ваш фасад должен определить единственный метод: PHPgetFacadeAccessor(). Его задача — определить, что вы хотите получить из контейнера. Класс PHPFacade использует магический метод PHP __callStatic() для перенаправления вызовов методов с вашего фасада на полученный объект.

Таким образом, когда вы делаете вызов фасада PHPCache::get, Laravel извлекает класс управления кэшем из IoC-контейнера и вызывает метод PHPget на класс. С технической точки зрения, фасады Laravel — удобный синтаксис для использования IoC-контейнера Laravel в качестве локатора служб.

Практическое использование

В примере ниже делается обращение к механизму кэширования Laravel. На первый взгляд может показаться, что метод PHPget() принадлежит классу PHPCache:

PHP
$value Cache::get('key');

Однако, если вы посмотрите в исходный код класса PHPIlluminate\Support\Facades\Cache, то увидите, что он не содержит метода PHPget():

PHP
class Cache extends Facade {

  
/**
   * Получить зарегистрированное имя компонента.
   *
   * @return string
   */
  
protected static function getFacadeAccessor() { return 'cache'; }

}

Класс PHPCache наследует класс PHPFacade и определяет метод PHPgetFacadeAccessor(). Как вы помните, его задача — вернуть имя привязки (типа) в контейнере IoC.

Когда вы обращаетесь к любому статическому методу фасада PHPCache, Laravel получает объект cache из IoC и вызывает на нём требуемый метод (в этом случае — PHPget()).

Таким образом, вызов PHPCache::get() может быть записан так:

PHP
$value $app->make('cache')->get('key');

Создание фасадов

Создать фасад в вашем приложении или пакете довольно просто. Вам нужны только три вещи:

  1. Связка в IoC.
  2. Класс-фасад.
  3. Настройка для псевдонима фасада.

Посмотрим на следующий пример. Здесь определён класс PHPPaymentGateway\Payment.

PHP
namespace PaymentGateway;

class 
Payment {

  public function 
process()
  {
    
//
  
}

}

Этот класс может находиться в вашем каталоге app/models или в любом другом каталоге, который добавлен в автозагрузку Composer.

Нам нужно, чтобы этот класс извлекался из контейнера IoC, так что давайте добавим для него привязку (binding):

PHP
App::bind('payment', function () {
  return new \
PaymentGateway\Payment;
});

Самое лучшее место для регистрации этой связки — новый поставщик услуг, который мы назовём PHPPaymentServiceProvider и в котором мы создадим метод PHPregister(), содержащий код выше. После этого вы можете настроить Laravel для загрузки этого поставщика в файле app/config/app.php.

Дальше мы можем написать класс нашего фасада:

PHP
use Illuminate\Support\Facades\Facade;

class 
Payment extends Facade {

  protected static function 
getFacadeAccessor() { return 'payment'; }

}

Наконец, по желанию можно добавить псевдоним (alias) для этого фасада в массив aliases файла настроек app/config/app.php — тогда мы сможем вызывать метод PHPprocess() на классе PHPPayment:

PHP
Payment::process();

Об автозагрузке псевдонимов

В некоторых случаях классы в массиве aliases не доступны из-за того, что PHP не загружает неизвестные классы в подсказках типов. Если PHP\ServiceWrapper\ApiTimeoutException имеет псевдоним PHPApiTimeoutException, то блок PHPtry ... catch (ApiTimeoutException $e), помещённый в любое пространство имён, кроме PHPServiceWrapper, никогда не «поймает» это исключение, даже если оно было возбуждено внутри него. Аналогичная проблема возникает в моделях, которые содержат подсказки типов на неизвестные (неопределённые) классы. Единственное решение — не использовать псевдонимы и вместо них в начале каждого файла писать PHPuse ... as для классов, которые вы хотите использовать в подсказках типов.

Фасады-заглушки

Юнит-тесты играют важную роль в том, почему фасады делают именно то, что они делают. На самом деле возможность тестирования — основная причина, по которой фасады вообще существуют. Эта тема подробнее раскрыта в соответствующем разделе документации.

Соответствие фасадов и классов

В таблице ниже перечислены все фасады и соответствующие им классы. Это полезный инструмент для быстрого начала работы с документацией по API данного корня фасадов. Также указаны ключи привязки IoC, где это нужно.

Фасад Класс Привязка IoC
App Illuminate\Foundation\Applicationapp
Artisan Illuminate\Console\Applicationartisan
AuthIlluminate\Auth\AuthManagerauth
Auth (экземпляр)Illuminate\Auth\Guard
BladeIlluminate\View\Compilers\BladeCompilerblade.compiler
CacheIlluminate\Cache\Repositorycache
ConfigIlluminate\Config\Repositoryconfig
CookieIlluminate\Cookie\CookieJarcookie
CryptIlluminate\Encryption\Encrypterencrypter
DBIlluminate\Database\DatabaseManagerdb
DB (экземпляр)Illuminate\Database\Connection
EventIlluminate\Events\Dispatcherevents
FileIlluminate\Filesystem\Filesystemfiles
FormIlluminate\Html\FormBuilderform
HashIlluminate\Hashing\HasherInterfacehash
HTMLIlluminate\Html\HtmlBuilderhtml
InputIlluminate\Http\Requestrequest
LangIlluminate\Translation\Translatortranslator
LogIlluminate\Log\Writerlog
MailIlluminate\Mail\Mailermailer
PaginatorIlluminate\Pagination\Environmentpaginator
Paginator (экземпляр)Illuminate\Pagination\Paginator
PasswordIlluminate\Auth\Reminders\PasswordBrokerauth.reminder
QueueIlluminate\Queue\QueueManagerqueue
Queue (экземпляр)Illuminate\Queue\QueueInterface
Queue (базовый класс)Illuminate\Queue\Queue
RedirectIlluminate\Routing\Redirectorredirect
RedisIlluminate\Redis\Databaseredis
RequestIlluminate\Http\Requestrequest
ResponseIlluminate\Support\Facades\Response
RouteIlluminate\Routing\Routerrouter
SchemaIlluminate\Database\Schema\Blueprint
SessionIlluminate\Session\SessionManagersession
Session (экземпляр)Illuminate\Session\Store
SSHIlluminate\Remote\RemoteManagerremote
SSH (экземпляр)Illuminate\Remote\Connection
URLIlluminate\Routing\UrlGeneratorurl
ValidatorIlluminate\Validation\Factoryvalidator
Validator (экземпляр)Illuminate\Validation\Validator
ViewIlluminate\View\Environmentview
View (экземпляр)Illuminate\View\View

Комментарии (2)

sait4seo
PHP
App::bind('payment', function () {
  return new \
PaymentGateway\Payment;
});
  1. этот код отработает при любом запуске приложения, даже если я не буду вызывать метод класса Payment ?
  2. как сделать так чтобы экземпляр класса создавался только если я использую методы его класса?
Proger_XP

Вам лучше задавать вопросы на форуме.

Написать комментарий

Разметка: ? ?

Авторизуйся, чтобы прокомментировать.