HTTP запросы

Получение экземпляра запроса

Для получения экземпляра текущего HTTP-запроса через внедрение зависимости вам надо указать тип класса Illuminate\Http\Request в методе вашего контроллера. Экземпляр входящего запроса будет автоматически внедрён сервис-контейнером:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class UserController extends Controller
{
    /**
     * Хранить нового пользователя.
     *
     * @param  Request  $request
     * @return Response
     */
    public function store(Request $request)
    {
        $name = $request->input('name');

        //
    }
}

Внедрение зависимости и параметры роута

Если метод вашего контроллера также ожидает ввода из параметров роута, вам надо перечислить параметры вашего роута после других зависимостей. Например, если ваш роут определён вот так:

Route::put('user/{id}', 'UserController@update');

То вы так же можете указать тип Illuminate\Http\Request и получить параметр id вашего роута, определив метод вашего контроллера таким образом:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class UserController extends Controller
{
    /**
     * Обновить указанного пользователя.
     *
     * @param  Request  $request
     * @param  string  $id
     * @return Response
     */
    public function update(Request $request, $id)
    {
        //
    }
}

Обращение к запросу через замыкания роутов

Также вы можете указать в качестве аргумента класс Illuminate\Http\Request в замыкании роута. Сервис-контейнер автоматически внедрит входящий запрос в замыкание при его выполнении:

use Illuminate\Http\Request;

Route::get('/', function (Request $request) {
    //
});

Методы и путь запроса

Экземпляр Illuminate\Http\Request содержит множество методов для изучения входящего в ваше приложение запроса. Он наследует класс Symfony\Component\HttpFoundation\Request. Ниже мы обсудим несколько наиболее полезных методов этого класса.

Получение пути запроса

Метод path возвращает информацию о пути запроса. Например, если входящий запрос обращён к http://domain.com/foo/bar, то метод path вернёт foo/bar:

$uri = $request->path();

Метод is позволяет проверить соответствие пути запроса заданной маске. При использовании этого метода можно использовать символ звёздочки * в качестве маски:

if ($request->is('admin/*')) {
    //
}

Получение URL запроса

Для получения полного URL без строки запроса используйте методы url или fullUrl. Метод url вернет URL без строки запроса, а метод fullUrl - со строкой запроса:

// Без строки запроса...
$url = $request->url();

// Со строкой запроса...
$url = $request->fullUrl();

Получение метода запроса

Метод method вернёт HTTP-действие запроса. Вы можете использовать метод isMethod для проверки соответствия HTTP-действия заданной строке:

$method = $request->method();

if ($request->isMethod('post')) {
    //
}

Запросы PSR-7

Стандарт PSR-7 описывает интерфейсы для HTTP-сообщений, включая запросы и отклики. Если вы хотите получить экземпляр запроса PSR-7 вместо Laravel-запроса, сначала вам надо установить несколько библиотек. Laravel использует компонент Symfony HTTP Message Bridge для конвертации обычных запросов и откликов Laravel в совместимые с PSR-7:

composer require symfony/psr-http-message-bridge
composer require zendframework/zend-diactoros

Когда вы установите эти библиотеки, вы можете получить запрос PSR-7, указав интерфейс запроса в замыкании вашего роута или методе контроллера:

use Psr\Http\Message\ServerRequestInterface;

Route::get('/', function (ServerRequestInterface $request) {
    //
});

{tip} IЕсли вы возвращаете экземпляр отклика PSR-7 из роута или контроллера, он будет автоматически конвертирован обратно в экземпляр отклика Laravel и будет отображён фреймворком.

Обрезка и нормализация ввода

По умолчанию Laravel включает посредников TrimStrings и ConvertEmptyStringsToNull в глобальном стеке посредников вашего приложения. Эти посредники перечислены в стеке по классу App\Http\Kernel. Данные посредники будут автоматически обрезать все поля входящих строк по запросу, а также конвертировать любые пустые поля строк в null. Это позволит вам не беспокоиться о проблемах нормализации в ваших роутах и контроллерах.

Если вы хотите отключить подобное поведение, то можете убрать двух посредников из стека посредников своего приложения, убрав их из свойства $middleware своего класса App\Http\Kernel.

Получение ввода

Получение всех данных ввода

Вы можете получить все данные ввода в виде массива с помощью метода all:

$input = $request->all();

Получения значения из ввода

Вы можете получить доступ ко всем введённым данным из экземпляра Illuminate\Http\Request, используя всего несколько простых методов. Вам не нужно думать о том, какой тип HTTP-запроса был использован, метод input работает одинаково для любого из них:

$name = $request->input('name');

Вы можете передать значение по умолчанию вторым аргументом метода input. Это значение будет возвращено, когда запрашиваемый ввод отсутствует в запросе:

$name = $request->input('name', 'Sally');

При работе с формами, имеющими переменные-массивы, вы можете использовать синтаксис с точкой для обращения к массивам:

$name = $request->input('products.0.name');

$names = $request->input('products.*.name');

Получение ввода через динамические свойства

Также вы можете получать пользовательский ввод, используя динамический свойства экземпляра Illuminate\Http\Request. Например, если одна из форм приложения содержит поле name, вы можете получить значение отправленного поля вот так:

$name = $request->name;

При использовании динамических свойств Laravel сначала ищет значение параметра в данных запроса. Если его там нет, Laravel будет искать поле в параметрах роута.

Получения значения из ввода JSON

При отправке JSON-запросов в приложение вы можете получить доступ к JSON-данным методом input , поскольку заголовок Content-Type запроса установлен в application/json. Вы даже можете использовать «точечный» синтаксис, чтобы погружаться в массивы JSON:

$name = $request->input('user.name');

Получение части переменных запроса

Если вам необходимо получить только часть данных ввода, используйте методы only и except. Оба этих метода принимают один массив или динамический список аргументов:

$input = $request->only(['username', 'password']);

$input = $request->only('username', 'password');

$input = $request->except(['credit_card']);

$input = $request->except('credit_card');

Метод only возвращает все пары ключ / значение, которые вы запрашиваете, даже если ключа нет во входящих запросах. Когда ключ не присутствует в запросе, значение будет null. Если вы хотите получить часть входных данных, которые действительно присутствуют в запросе, можно использовать метод intersect:

$input = $request->intersect(['username', 'password']);

Была ли передана переменная?

Вы должны использовать метод has, чтобы определить присутствует ли значение в запросе. Метод has вернёт true, если значение присутствует и не является пустой строкой:

if ($request->has('name')) {
    //
}

Когда передается массив, метод has определит присутствуют ли все указанные значения:

if ($request->has(['name', 'email'])) {
    //
}

Старый ввод

Laravel позволяет сохранить ввод от одного запроса во время следующего запроса. Это может пригодиться во время повторного наполнения форм после обнаружения ошибок валидации. Однако, если вы используете включённые в Laravel возможности проверки ввода, то вряд ли вам понадобиться использовать эти методы вручную, так как встроенные возможности Laravel вызовут их автоматически.

Передача ввода в сессию

Метод flash класса Illuminate\Http\Request передаст текущий ввод в сессию, и он будет доступен во время следующего пользовательского запроса к приложению:

$request->flash();

Вы также можете использовать методы flashOnly и flashExcept для передачи некоторых переменных в сессию. Эти методы полезны для хранения важной информации (например, паролей) вне сессии:

$request->flashOnly(['username', 'email']);

$request->flashExcept('password');

Передача ввода и последующее перенаправление

Поскольку часто требуется передать ввод в сессии и затем перенаправить на предыдущую страницу, вы можете легко прицепить передачу ввода к перенаправлению с помощью метода withInput:

return redirect('form')->withInput();

return redirect('form')->withInput(
    $request->except('password')
);

Получение старого ввода

Для получения переданного ввода из предыдущего запроса используйте метод old на экземпляре Request. Метод old получит переданные ранее данные ввода из сессии:

$username = $request->old('username');

В Laravel есть также и глобальный хелпер old. Когда вы выводите старый ввод в шалоне Blade, удобнее использовать этот хелпер old. Если для данного поля нет старого ввода, вернётся null:

<input type="text" name="username" value="{{ old('username') }}">

Cookies

Получение Cookies из запросов

Все cookie, создаваемые Laravel, шифруются и подписываются специальным кодом — таким образом, если клиент изменит их значение, то они станут недействительными. Для получения значения cookie из запроса используйте метод cookie на экземпляре Illuminate\Http\Request:

$value = $request->cookie('name');

Добавление cookie к ответам

Вы можете прикрепить cookie к исходящему экземпляру Illuminate\Http\Response с помощью метода cookie. Вы должны передать в этот метод имя, значение и количество минут, в течение которого cookie должен считаться действующим:

return response('Hello World')->cookie(
    'name', 'value', $minutes
);

Метод cookie также принимает ещё несколько аргументов, используемых менее часто. В целом эти аргументы имеют то же назначение и значение, что и передаваемые в PHP-метод setcookie аргументы:

return response('Hello World')->cookie(
    'name', 'value', $minutes, $path, $domain, $secure, $httpOnly
);

Генерация экземпляров Cookie

Если вы хотите сгенерировать экземпляр Symfony\Component\HttpFoundation\Cookie, который позднее можно будет передать экземпляру отклика, используйте глобальный хелпер cookie. Этот cookie не будет отправлен обратно клиенту до тех пор, пока не будет прикреплён к экземпляру отклика:

$cookie = cookie('name', 'value', $minutes);

return response('Hello World')->cookie($cookie);

Файлы

Получение загруженных файлов

Получить доступ к загруженным файлам из экземпляра Illuminate\Http\Request можно с помощью метода file или динамических свойств. Метод file возвращает экземпляр класса Illuminate\Http\UploadedFile, , который наследует PHP-класс SplFileInfo и предоставляет различные методы для взаимодействия с файлами:

$file = $request->file('photo');

$file = $request->photo;

Вы можете определить, есть ли в запросе файл, с помощью метода hasFile:

if ($request->hasFile('photo')) {
    //
}

Прошёл ли загруженный файл проверку?

Вдобавок к проверке наличия файла вы можете проверить, что при загрузке файла не возникло никаких проблем, с помощью метода isValid:

if ($request->file('photo')->isValid()) {
    //
}

Пути и расширения файла

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

$path = $request->photo->path();

$extension = $request->photo->extension();

Другие методы для работы с файлами

Есть множество других методов для экземпляров UploadedFile. Загляните в документацию API класса для получения более подробной информации об этих методах.

Хранение загруженных файлов

Для хранения загруженного файла обычно используется одна из настроенных файловых систем. В классе UploadedFile есть метод store, который переместит загруженный файл на один из ваших дисков, который может располагаться в вашей локальной файловой системе или даже в облачном хранилище, таком как Amazon S3.

Метод store принимает путь, куда необходимо сохранить файл относительно настроенного корневого каталога файловой системы. Этот путь не должен включать имя файла, поскольку будет автоматически сгенерирован UUID в качестве имени файла.

Также метод store принимает второй необязательный аргумент — имя диска для сохранения файла. Этот метод вернёт путь файла относительно корня диска:

$path = $request->photo->store('images');

$path = $request->photo->store('images', 's3');

Если вы не хотите автоматически генерировать имя файла, используйте метод storeAs, который принимает аргументы: путь, имя файла и имя диска:

$path = $request->photo->storeAs('images', 'filename.jpg');

$path = $request->photo->storeAs('images', 'filename.jpg', 's3');