{{TOC}} {{DOCVER 5.3=c06d6a2352ed8c767633aab9c20f2bf7d880c967 28.01.2017 5:00:51, 5.2=6b0b057ae6de3c88cb29188459e38383c622ec23 8.12.2016 23:00:15, 5.1=cdc24ba7426c5b11eb4d050706bd78c3ea4913cc 19.06.2016 20:08:01, 5.0=5d10040a981deee82c0fde0e8e5d2ffc49eaaecb 8.02.2016 18:09:11}} == Введение == Фасады предоставляют "статический" интерфейс к классам, доступным в ((docs/v5/container сервис-контейнере)). Laravel поставляется со множеством фасадов, предоставляющих доступ почти ко всем возможностям Laravel. Фасады Laravel служат "статическими прокси" для классов в сервис-контейнере, обеспечивая преимущества краткого выразительного синтаксиса, и поддерживая большую тестируемость и гибкость, чем традиционные статические методы. %%(DOCNEW 5.3=c06d6a2352ed8c767633aab9c20f2bf7d880c967 28.01.2017 5:00:51) Все фасады Laravel определены в пространстве имён %%(t)Illuminate\Support\Facades%%. Поэтому мы можем легко обратиться к фасаду таким образом: ~%% use Illuminate\Support\Facades\Cache; Route::get('/cache', function () { return Cache::get('key'); }); ~%% Во многих примерах в документации по Laravel используются фасады для демонстрации различных возможностей фреймворка. == Когда стоит использовать фасады == Фасады имеют много преимуществ. Они обеспечивают лаконичный, запоминающийся синтаксис, который позволяет вам использовать возможности Laravel, не запоминая длинные имена классов, которые должны внедряться или настраиваться вручную. Более того, благодаря уникальному использованию динамических методов PHP они легко тестируются. Тем не менее, при использовании фасадов необходимо соблюдать некоторые предосторожности. Основная опасность фасадов - разрастание границ класса. Поскольку фасады так просты в использовании и не требуют внедрения, становится очень вероятна ситуация, когда ваши классы постоянно продолжают расти, и когда в одном классе используется множество фасадов. При использовании внедрения зависимостей риск возникновения такой ситуации снижается за счёт того, что при виде большого конструктора вы можете визуально оценить увеличение размера вашего класса. Поэтому при использовании фасадов обратите особое внимание на размер вашего класса, чтобы границы его ответственности оставались узкими. .(alert) При создании стороннего пакета, взаимодействующего с Laravel, лучше внедрять ((//docs/v5/contracts контракты 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, и ваши собственные, наследуют базовый класс %%(t)Illuminate\Support\Facades\Facade%%. Базовый класс %%Facade%% использует ((phpdoc:language.oop5.overloading магический метод PHP)) %%__callStatic()%% для перенаправления вызовов методов с вашего фасада на полученный объект. В примере ниже делается обращение к механизму кэширования Laravel. На первый взгляд может показаться, что метод %%get()%% принадлежит классу %%Cache%%: %% $user]); } } %% Обратите внимание, в начале мы "импортируем" фасад %%(t)Cache%%. Этот фасад служит переходником для доступа к лежащей в основе реализации интерфейса %%(t)Illuminate\Contracts\Cache\Factory%%. Все выполняемые через этот фасад вызовы передаются ниже - в экземпляр кэш-сервиса Laravel. Если вы посмотрите в исходный код класса %%(t)Illuminate\Support\Facades\Cache%%, то увидите, что он не содержит метода %%get()%%: %% class Cache extends Facade { /** * Получить зарегистрированное имя компонента. * * @return string */ protected static function getFacadeAccessor() { return 'cache'; } } %% Вместо этого, фасад %%(t)Cache%% наследует базовый класс %%Facade%% и определяет метод %%getFacadeAccessor()%%. Его задача - вернуть имя //привязки// в сервис-контейнере. Когда вы обращаетесь к любому статическому методу фасада %%(t)Cache%%, Laravel получает по привязке объект %%(t)cache%% из ((/docs/v5/container сервис-контейнера)) и вызывает на нём требуемый метод (в этом случае - %%get()%%). %%(DOCNEW 5.0=5d10040a981deee82c0fde0e8e5d2ffc49eaaecb 8.02.2016 18:09:11) Таким образом, вызов %%Cache::get()%% может быть переписан так: ~%% $value = $app->make('cache')->get('key'); ~%% **Импорт фасадов** Помните, если вы используете фасад в контроллере, который находится в пространстве имён, то вам надо импортировать класс фасада в пространство имён. Все фасады живут в глобальном пространстве имён: ~%%