Laravel - Фасады

# Справочное описание классов фасадов
ВВЕДЕНИЕ
Фасады предоставляют "статический" интерфейс к классам, доступным в сервис-контейнере. Laravel поставляется со множеством фасадов, которые предоставляют доступ практически ко всем функциям Laravel. Фасады Laravel служат "статическими прокси" для основополагающих классов в сервис-контейнере, предоставляя преимущество лаконичного, выразительного синтаксиса, сохраняя при этом большую тестируемость и гибкость по сравнению с обычными статическими методами.
Все фасады Laravel определены в пространстве имен Illuminate \ Support \ Facades. Таким образом, мы можем легко получить доступ к фасаду:
use Illuminate\Support\Facades\Cache;
Route::get('/cache', function () {
return Cache::get('key');
});
В документации Laravel фасады будут использоваться во многих примерах, чтобы продемонстрировать различный функционал фреймворка.
КОГДА ИСПОЛЬЗОВАТЬ ФАСАДЫ
У фасадов множество преимуществ. Они обеспечивают лаконичный, запоминающийся синтаксис, который позволяет использовать функции Laravel без необходимости запоминать длинные названия классов, которые нужно вставить или настроить вручную. Кроме того, из-за их уникального использования динамических методов PHP, их легко тестировать.
Однако при использовании фасадов необходимо проявлять определенную осторожность. Основная опасность фасадов - расширение области ответственности класса. Поскольку фасады настолько просты в использовании и не требуют внедрения, легко будет позволить вашим классам продолжать расти и использовать много фасадов в одном классе. При использовании внедрения зависимостей этот потенциал подавляется визуальной обратной связью, которую дает большой конструктор относительно того, что ваш класс становится слишком большим - т.е. однажды вы посмотрите на конструктор с множеством подключённых сторонних классов и подумаете "что-то я тут увлёкся. разобью-ка этот класс на два", а при использовании фасадов накопление сторонних зависимостей в классе проходит гораздо незаметнее. Поэтому при использовании фасадов обращайте особое внимание на размер вашего класса, чтобы его область ответственности оставалась малой, чтобы он делал одну узкоспециализированную задачу.
{совет} При создании стороннего пакета, который взаимодействует с Laravel, лучше внедрять контракты Laravel вместо использования фасадов. Так как пакеты создаются вне самого Laravel, у вас не будет доступа к хелперам тестирования Laravel.
Фасады в сравнении с Внедрением зависимостей
Одним из основных преимуществ внедрения зависимостей является возможность замены реализаций внедряемого класса. Это полезно во время тестирования, так как вы можете внедрить заглушку и утверждать, что на заглушке есть различные методы.
Для настоящих статических методов обычно невозможно сделать заглушку. Однако, поскольку фасады используют динамические методы для вызова метода прокси для объектов, отделенных от сервис-контейнеров, мы фактически можем тестировать фасады так же, как мы бы тестировали экземпляр внедренного класса. Например, учитывая следующий роут:
use Illuminate\Support\Facades\Cache;
Route::get('/cache', function () {
return Cache::get('key');
});
Мы можем написать следующий тест, чтобы проверить, что метод Cache::get был вызван с ожидаемым аргументом:
use Illuminate\Support\Facades\Cache;
/**
* Пример базового функционального теста.
*
* @return void
*/
public function testBasicExample()
{
Cache::shouldReceive('get')
->with('key')
->andReturn('value');
$this->visit('/cache')
->see('value');
}
Фасады в сравнении с Хелперами
Помимо фасадов, Laravel включает множество вспомогательных функций, хелперов, которые могут выполнять общие задачи, такие как формирование шаблонов, запуск событий, постановка задач в очередь или отправка HTTP-ответов. Многие из этих хелперов выполняют ту же функцию, как и соответствующий фасад. Например, этот вызов фасада и этот вызов хелпера эквивалентны:
return View::make('profile');
return view('profile');
Нет никакой практической разницы между фасадами и хелперами. При использовании хелперов вы можете тестировать их точно так же, как и соответствующие фасады. Например, учитывая следующий роут:
Route::get('/cache', function () {
return cache('key');
});
С точки зрения внутренней структуры, помощник cache собирается вызвать метод get в классе, основополагающем для фасада Cache . Поэтому, хотя мы используем вспомогательную функцию, мы можем написать следующий тест, чтобы убедиться, что метод был вызван с ожидаемым аргументом:
use Illuminate\Support\Facades\Cache;
/**
* Пример базового функционального теста.
*
* @return void
*/
public function testBasicExample()
{
Cache::shouldReceive('get')
->with('key')
->andReturn('value');
$this->visit('/cache')
->see('value');
}
КАК РАБОТАЮТ ФАСАДЫ
В контексте приложения на Laravel, фасад - это класс, который предоставляет доступ к объекту в контейнере. Весь этот механизм реализован в классе Facade. Фасады как Laravel, так и ваши собственные, наследуют этот базовый класс Illuminate \ Support \ Facades \ Facade.
Класс Facade использует магический метод PHP __callStatic() для перенаправления вызовов методов с вашего фасада на полученный объект из контейнера. В примере ниже делается обращение к механизму кэширования Laravel. На первый взгляд может показаться, что статический метод get принадлежит классу Cache:
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Cache;
class UserController extends Controller
{
/**
* Показать профиль для данного пользователя.
*
* @param int $id
* @return Response
*/
public function showProfile($id)
{
$user = Cache::get('user:'.$id);
return view('profile', ['user' => $user]);
}
}
Обратите внимание, что в верхней части файла мы "импортируем" фасад Cache. Этот фасад служит прокси-сервером для доступа к базовой реализации интерфейса Illuminate \ Contracts \ Cache \ Factory. Любые вызовы, которые мы осуществляем с использованием фасада, будут переданы в исходный сервис кэша Laravel.
Однако, если вы посмотрите в исходный код класса Illuminate \ Support \ Facades \ Cache, то увидите, что он не содержит метода get:
class Cache extends Facade
{
/**
* Получить зарегистрированное имя компонента.
*
* @return string
*/
protected static function getFacadeAccessor() { return 'cache'; }
}
Вместо этого фасад Cache расширяется на базе класса Facade и определяет метод getFacadeAccessor(). Задача этого метода - вернуть строковое имя (ключ) привязки объекта в сервис-контейнере. Когда вы обращаетесь к любому статическому методу фасада Cache, Laravel получает объект cache из сервис-контейнера и вызывает у него требуемый метод (в этом случае - get).
СПРАВОЧНОЕ ОПИСАНИЕ КЛАССОВ ФАСАДОВ
Ниже вы найдете каждый фасад и его основной класс. Это полезный инструмент для быстрой обработки документации API для данной корневой директории фасада. Ключ привязки сервис-контейнера также включен там, где это применимо.
ФАСАД | КЛАСС | ПРИВЯЗКА СЕРВИС-КОНТЕЙНЕРА |
App | Illuminate\Foundation\Application | app |
Artisan | Illuminate\Contracts\Console\Kernel | artisan |
Auth | Illuminate\Auth\AuthManager | auth |
Blade | Illuminate\View\Compilers\BladeCompiler | blade.compiler |
Bus | Illuminate\Contracts\Bus\Dispatcher | |
Cache | Illuminate\Cache\Repository | cache |
Config | Illuminate\Config\Repository | config |
Cookie | Illuminate\Cookie\CookieJar | cookie |
Crypt | Illuminate\Encryption\Encrypter | encrypter |
DB | Illuminate\Database\DatabaseManager | db |
DB (Instance) | Illuminate\Database\Connection | |
Event | Illuminate\Events\Dispatcher | events |
File | Illuminate\Filesystem\Filesystem | files |
Gate | Illuminate\Contracts\Auth\Access\Gate | |
Hash | Illuminate\Contracts\Hashing\Hasher | hash |
Lang | Illuminate\Translation\Translator | translator |
Log | Illuminate\Log\Writer | log |
Illuminate\Mail\Mailer | mailer |
|
Notification | Illuminate\Notifications\ChannelManager | |
Password | Illuminate\Auth\Passwords\PasswordBrokerManager | auth.password |
Queue | Illuminate\Queue\QueueManager | queue |
Queue (Instance) | Illuminate\Contracts\Queue\Queue | queue |
Queue (Base Class) | Illuminate\Queue\Queue | |
Redirect | Illuminate\Routing\Redirector | redirect |
Redis | Illuminate\Redis\Database | redis |
Request | Illuminate\Http\Request | request |
Response | Illuminate\Contracts\Routing\ResponseFactory | |
Route | Illuminate\Routing\Router | router |
Schema | Illuminate\Database\Schema\Blueprint | |
Session | Illuminate\Session\SessionManager | session |
Session (Instance) | Illuminate\Session\Store | |
Storage | Illuminate\Contracts\Filesystem\Factory | filesystem |
URL | Illuminate\Routing\UrlGenerator | url |
Validator | Illuminate\Validation\Factory | validator |
Validator (Instance) | Illuminate\Validation\Validator | |
View | Illuminate\View\Factory | view |
View (Instance) | Illuminate\View\View |
Источник
Вопросы / Комментарии / Отзывы