Ответы

Содержание:


Создание ответов

Строки и массивы

Все маршруты и контроллеры должны возвращать ответ, который высылается обратно пользователю в браузер. Ларавел обеспечивает несколько различных путей возврата ответов. Наиболее простой ответ вернёт строку из маршрута или контроллера. Фреймворк автоматически конвертирует строку в полноценный HTTP ответ:

Route::get('/', function () {
    return 'Hello World';
});

В дополнение к возврату строк из контроллера или маршрута, вы также можете возвращать массивы. Фреймворк автоматически конвертирует массив в JSON ответ:

Route::get('/', function () {
    return [1, 2, 3];
});
Также можно вернуть коллекции Eloquent из вашего маршрута или контроллера. Они автоматически конвертируются в JSON.

Объекты в качестве ответов

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

Возвращение экземпляра Response позволяет вам настроить HTTP статус код и заголовки. Экземпляр Response наследуется от класса Symfony\Component\HttpFoundation\Response, который обеспечивает набор методов для построения ответа HTTP:

Route::get('home', function () {
    return response('Hello World', 200)
                  ->header('Content-Type', 'text/plain');
});

Приклепление заголовка к ответу

Возьмите на заметку, что большинство методов ответа можно представить как звенья цепи, что ползволяет гибки конструировать экземпляр ответа. Например, вы можете использовать метод header, чтобы добавлять заголовки для ответа до момента отправки их обратно пользователю:

return response($content)
            ->header('Content-Type', $type)
            ->header('X-Header-One', 'Header Value')
            ->header('X-Header-Two', 'Header Value');

Или, можно использовать метод withHeaders, чтобы указать массив заголовков, которые необходимо добавить к ответу:

return response($content)
            ->withHeaders([
                'Content-Type' => $type,
                'X-Header-One' => 'Header Value',
                'X-Header-Two' => 'Header Value',
            ]);

Посредник контроля кэша

Laravel включает посредника cache.headers, который может быть использовн для быстрого установления заголовка Cache-Control для группы маршрутов. Если etag указан в списке директив, хэш MD5 содержимого ответа автоматически будет установлен с идентификатором ETag:

Route::middleware('cache.headers:public;max_age=2628000;etag')->group(function() {
    Route::get('privacy', function () {
        // ...
    });

    Route::get('terms', function () {
        // ...
    });
});

Приклепление файлов Cookies к ответу

Метод cookie для экземпляра ответа позволяет вам легко прикрепить cookies к ответу. Например, вы можете использовать метод cookie, чтобы сгенерировать cookie и быстро прикрепить к ответу так:

return response($content)
                ->header('Content-Type', $type)
                ->cookie('name', 'value', $minutes);

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

->cookie($name, $value, $minutes, $path, $domain, $secure, $httpOnly)

Как альтернатива, вы можете использовать фасад Cookie чтобы добавить в очередь cookie для вложения в исходящий ответ для вашего приложения. Метод queue принимает экземпляр Cookie или аргументы, которые необходимы для создания экземпляра Cookie. Эти cookie будут прикреплены к исходящему ответу до того, как он отправлен в браузер:

Cookie::queue(Cookie::make('name', 'value', $minutes));

Cookie::queue('name', 'value', $minutes);

Cookies и шифрование

По умолчанию, все cookies сгенерированные Laravel зашифрованы и подписаны, поэтому клиент не может из прочитать или модифицировать. Если вы хотите отключить шифрование для набора cookie сгенерированных приложением, вы можете использовать свойство $except посредника App\Http\Middleware\EncryptCookies, который расположен в папке app/Http/Middleware:

/**
 * The names of the cookies that should not be encrypted.
 *
 * @var array
 */
protected $except = [
    'cookie_name',
];

Перенаправления

Класс Illuminate\Http\RedirectResponse перенаправляет ответы и содержит заголовки, необходимы для перенаправления пользователя на другой URL. Есть несколько путуей, чтобы сгенерировать экземпляр RedirectResponse. Самый простой метод — это использовать глобальный помощник redirect:

Route::get('dashboard', function () {
    return redirect('home/dashboard');
});

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

Route::post('user/profile', function () {
    // Validate the request...

    return back()->withInput();
});

Перенаправление на названные маршруты

Если вызвать помощник redirect без параметров, вернйтся экземпляр Illuminate\Routing\Redirector, который позволит вам вызвать любой метод для экземпяляра Redirector. Например, чтобы сгенерировать RedirectResponse для названного маршрут, вы можете использовать метод route:

return redirect()->route('login');

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

// For a route with the following URI: profile/{id}

return redirect()->route('profile', ['id' => 1]);

Заполнение параметров с помощью меоделей Eloquent

Если вы перенаправляете на маршрут с параметром "ID", который заполнялся через модель Eloquent, вы можете передать саму модель. ID будет передан автоматически:

// For a route with the following URI: profile/{id}

return redirect()->route('profile', [$user]);

Если вы хотите настроить значение, которое размещено в параметре маршрута, вы должны переписать метод getRouteKey для модели Eloquent:

/**
 * Get the value of the model's route key.
 *
 * @return mixed
 */
public function getRouteKey()
{
    return $this->slug;
}

Перенаправление на действие контроллера

Вы также можете сгенерировать перенаправления на действие контроллера. Чтобы это сделать, передайте название действия и контроллер в метод action. Вам не нужно указывать полный путь пространсва имен к контроллеру, потому что RouteServiceProvider Ларавел автоматически установить базовое пространство имён:

return redirect()->action('HomeController@index');

Если ваш контроллер маршрута требует параметры, вы можете передать их вторым аргументов в метод action:

return redirect()->action(
    'UserController@profile', ['id' => 1]
);

Перенаправление на внешние домены

Иногда вам необходимо перенаправить на домен вне вашего приложения. Чтобы сделать так, вызовите метод away, который создаст RedirectResponse без любого дополнительного кодирования URL, валидации или верификации:

return redirect()->away('https://www.google.com');

Перенаправление с данными сессии

Перенаправление на новый URL и передача временных данных в сессию практически всегда происходит одномоментно. Типовая ситуация, когда после успешного выполнения действия, вы передаёте временное сообщение об успехе в сессию. Для удобства, вы можете создать экземпляр RedirectResponse и передовать временные данные в сессию одним простым методом:

Route::post('user/profile', function () {
    // Update the user's profile...

    return redirect('dashboard')->with('status', 'Profile updated!');
});

После того, как пользователя перенаправили, вы можете показать сообщение из сессии. Например, используя синтаксис Blade:

@if (session('status'))
    <div class="alert alert-success">
        {{ session('status') }}
    </div>
@endif

Другие типы ответов

Помощник response может быть использован, чтобы сгенерировать другие типы ответов. Когда мы вызываем помощника response без аргументов, возвращается реализация контракта Illuminate\Contracts\Routing\ResponseFactory. Этот контракт предоставляет несколько полезным методов для генерации ответов.

Ответы представления

Если вам необходим контроль за статусом ответа и заголовки, но ещё нужно вернуть представление к качестве содержимого ответа, вы должны использовать метод view:

return response()
            ->view('hello', $data, 200)
            ->header('Content-Type', $type);

Конечно, если вам не нужно передавать код статуса HTTP или пользовательские заголовки, тогда вам необходимо использовать глобальную функцию-помощнник view.

JSON ответы

Метод json автоматически присвоит заголовоку Content-Type значение application/json, также как и конвертирует данный массив в JSON используя функцию PHP json_encode:

return response()->json([
    'name' => 'Abigail',
    'state' => 'CA'
]);

Если вы хотите создать ответ JSONP, вы можете использовать метод json в комбинации с методом withCallback:

return response()
            ->json(['name' => 'Abigail', 'state' => 'CA'])
            ->withCallback($request->input('callback'));

Загрузка файлов

Метод download можно использовать, чтобы сгенерировать ответ, который заставляет браузер пользователя загружать файл по данному пути. Метод принимет имя файла в качестве второго аргумента, который определяет имя файла для пользователя при загрузке. Наконец, вы можете передать массив заголовков HTTP в качестве третьего аргумента в метод:

return response()->download($pathToFile);

return response()->download($pathToFile, $name, $headers);

return response()->download($pathToFile)->deleteFileAfterSend();
HttpFoundation фреймворка Symfony, которое управляет загрузкой файла, требует чтобы файл имел имя ASCII.

Загрузка "на лету"

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

return response()->streamDownload(function () {
    echo GitHub::api('repo')
                ->contents()
                ->readme('laravel', 'laravel')['contents'];
}, 'laravel-readme.md');

Ответы с файлами

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

return response()->file($pathToFile);

return response()->file($pathToFile, $headers);

Макросы ответа

Если вы хотите определить пользовательский ответ, который вы можете повторно использовать в ваших маршрутах и контроллерах, вы можете использовать метод macro для фасада Response. Например, из метода boot сервис провайдера:

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Response;

class ResponseMacroServiceProvider extends ServiceProvider
{
    /**
     * Register the application's response macros.
     *
     * @return void
     */
    public function boot()
    {
        Response::macro('caps', function ($value) {
            return Response::make(strtoupper($value));
        });
    }
}

Функция macro макро принимает имя в качестве первого аргумента, и замыкание как второй аргумент. Замыкание будет выполняться при обращении из реализации ResponseFactory или из функции-помощника response:

return response()->caps('foo');