{{TOC}} При наследовании Illuminate-класса %%Request%% и класса %%Response%% возникает некоторая путаница. Эти два класса работают несколько иначе, чем обычные классы из-за их важности в обработке HTTP-запросов. Я расскажу, как их наследовать, а потом покажу метод, который показывает, **как композиция может быть лучше наследования**. == Наследование класса %%Response%% == Сначала я опишу наследование класса %%Response%%, так как оно проще. Обычно в Illuminate-библиотеках есть класс, который содержит основную массу функциональных возможностей этой библиотеки. Этот класс часто имеет соответствующий фасад, который предоставляет разработчикам "простой" доступ к его методам. Поэтому мы можем просто вызывать %%Auth::guest()%% или %%Redirect::route()%%. Illuminate-класс Response - %%Illuminate\Http\Response%%. Но его фасад %%Illuminate\Support\Facades\Response%% отличается от остальных. Вместо наследования %%Facade%% он представляет собой //собственный// маленький одинокий класс. То есть это не "лицо" %%Illuminate\Http\Response%%, а скорее он просто **использует** класс %%Response%%: %% # Файл Illuminate/Support/Facades/Response.php class Response { /** * Вернуть новый объект ответа приложения. * * @param string $content * @param int $status * @param array $headers * @return Symfony\Component\HttpFoundation\Response */ public static function make($content = '', $status = 200, array $headers = array()) { return new \Illuminate\Http\Response($content, $status, $headers); } %% .(alert) **Примечание:** фасад класса Response в Laravel не использует %%Illuminate\Http\Response%% для всех своих ответов. Он использует классы Symfony для ответов JSON, Stream и Download. Итак, как нам наследовать этот класс? К счастью, это не так сложно! Оказывается, нам вообще не надо иметь дело с фасадами, что делает всё ещё проще. **Во-первых, зададим для класса наследование "фасада" %%Response%%:** %% 'yay!']); } } %% **Во-вторых, заменим фасад Response в Laravel на свой.** Учитывая, что ваша автозагрузка будет обрабатывать этот класс (см. мою статью ((http://fideloper.com/laravel-4-application-setup-app-library-autoloading==Установка библиотеки приложения Laravel))), ваш следующий шаг - просто заменить фасад %%Response%% Laravel вашим собственным. Зайдите в %%(t)app/config/app.php%% и добавьте ваш класс %%Response%% вместо того, что указан в Laravel по умолчанию: %% # Файл: app/config/app.php 'aliases' => array( ... прочие алиасы ... 'Redis' => 'Illuminate\Support\Facades\Redis', 'Request' => 'Illuminate\Support\Facades\Request', //'Response' => 'Illuminate\Support\Facades\Response', 'Response' => 'Fideloper\Example\Facades\Response', ... больше алиасов ... ) %% И вуаля! Вы можете использовать %%Response::DoSomething()%% как пожелаете! == Наследование класса %%Request%% == С классом %%Request%% сложнее. Его наследование не так изящно и просто. Сложность в том, что он используется в самом начале выполнения Laravel. Давайте посмотрим. Откройте %%(t)public/index.php%% %% // Комментарии удалены: require __DIR__.'/../bootstrap/autoload.php'; $app = require_once __DIR__.'/../bootstrap/start.php'; $app->run(); $app->shutdown(); %% Обратите внимание, что вторым вызывается файл %%(t)bootstrap/start.php%%. Давайте посмотрим на этот файл: %% // Комментарии удалены: $app = new Illuminate\Foundation\Application; $env = $app->detectEnvironment(array( 'local' => array('your-machine-name'), )); ... Больше кода ... %% Сначала создается класс приложения %%Application%%. Затем в %%(t)Illuminate\Foundation\Application%% происходит следующее: %% public function __construct(Request $request = null) { $this['request'] = $this->createRequest($request); ... Больше кода ... } protected function createRequest(Request $request = null) { return $request ?: Request::createFromGlobals(); } %% Таким образом, в классе %%Application%% первым происходит создание (и "заполнение") объекта %%Request%%. Мы видим, что объект %%Request%% создается в самом начале обработки запроса клиента. Он не только создается, но и заполняется информацией HTTP-запросов (заголовками, параметрами и т.д.). Это происходит до того, как вызываются какие-либо события (%%Events%%), и регистрируются какие-либо сервис-провайдеры или псевдонимы (фасады). **Это означает, что если мы перепишем классы ядра Laravel с помощью обычных инструментов (обычно через сервис-провайдер), то мы просто заменим объект приложения %%Request%% на пустой.** Я допустил эту ошибку - я использовал сервис-провайдер и просто заменил старый объект %%Request%% своим собственным. Я даже вызывал %%Request::createFromGlobals()%%, чтобы мой объект мог так же получить информацию о запросе. Однако это не работало. В конечном счёте объект запроса создавался дважды (один в классе %%Application%%, другой в моём сервис-провайдере). Когда запрос создается в первый раз, то он, по-видимому, сбрасывает часть информации о самом запросе (в целях безопасности?). Поэтому один из вариантов для нас - отредактировать %%bootstrap/start.php%% и передать наш собственный класс %%Request%%. **Во-первых, создадим класс %%Request%%:** %% request = $request; } public function doSomething() { $somethingHeader = $this->request->header('нечто'); return $somethingHeader; } } %% Чтобы сделать еще один шаг вперед вы можете создать фасады для этих классов, как описано в ((17 этой статье)). Как уже упоминалось, приведенный код использует классы %%Request%%/%%Response%% Laravel, а не наследует их. Использование интерфейсов может сделать их независимыми от фреймворка, позволяя вам реализовать класс для любой ситуации (использовать в других фреймворках или библиотеках). **Если вы придерживаетесь только Laravel, то можете вообще не использовать интерфейсы.**