среда, 5 июля 2017 г.

LARAVEL. ФОРМИРОВАНИЕ ОТВЕТА. КЛАСС RESPONSE

Откроем app\Http\Controllers\Admin\AboutController.php


class AboutController extends Controller
{
public function show() {
return 'hello'; // сформируем ответ
if(view()->exists('default.about')) {
return view('default.about')->withTitle('Hello World');
}
abort(404);
}
}

Наберем: http://tlaravel.loc/about
На странице отобразится: hello

Откроем глобальную точку входа public\index.php

$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
$response = $kernel->handle(
$request = Illuminate\Http\Request::capture()
);

$response->send(); //
Объект отправляется пользователю при вызове метода send


Объект класса response — абстракция ответа, которая формируется приложением.

Класс response описан по адресу: vendor\laravel\framework\src\Illuminate\Http\Response.php

Класс Response использует функционал трейта ResponseTrait, который находится в этом каталоге.

Откроем: vendor\symfony\http-foundation\Response.php
Здесь описан родительский класс Response. Здесь находим метод send, который отправляет ответ пользователю.

public function send()
{
$this->sendHeaders(); // отправка заголовков
$this->sendContent(); // отправка контента

if (function_exists('fastcgi_finish_request')) {
fastcgi_finish_request();
} elseif ('cli' !== PHP_SAPI) {
static::closeOutputBuffers(0, true);
}

return $this;
}
В родительском классе также описан метод конструктор. Конструктор нужен, чтобы узнать какие параметры мы можем передавать при создании объекта класса Response.

public function __construct($content = '', $status = 200, $headers = array())
{
$this->headers = new ResponseHeaderBag($headers);
$this->setContent($content);
$this->setStatusCode($status);
$this->setProtocolVersion('1.0');

/* RFC2616 - 14.18 says all Responses need to have a Date */
if (!$this->headers->has('Date')) {
$this->setDate(\DateTime::createFromFormat('U', time()));
}
}

Первым аргументом мы можем передать контент, который будет отображен на экране пользователя. Второй аргумент — код статуса ответа. По умолчанию это 200, т.е означает, что все нормально. Третий параметр — заголовки.



Откроем app\Http\Controllers\Admin\AboutController.php и вернем объект класса Response:

<?php

namespace App\Http\Controllers\Admin;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Http\Response; // предоставим доступ к классу Response. Если мы не добавим эту строку, будет сгенерировнно сключение.

class AboutController extends Controller
{
public function show() {

if(view()->exists('default.about')) {
// return (new Response('hello', 200, array()));
return (new Response('hello'); // предадим только первый параметр //return view('default.about')->withTitle('Hello World');
}
abort(404);
}
}

Заголовки будут сформированы автоматически.

Наберем: http://tlaravel.loc/about
На странице отобразится: hello
Теперь мы возвращаем объект класса Response.

Отобразим данные на экране с использованием конкретного вида:
<?php

namespace App\Http\Controllers\Admin;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

use Illuminate\Http\Response; // предоставим доступ к классу Response. Если мы не добавим эту строку, будет сгенерировнно сключение.

class AboutController extends Controller
{
public function show() {

if(view()->exists('default.about')) {
$view = view('default.about')->withTitle('Hello World')->render();
return (new Response($view));


}
abort(404);
}
}

Добавим набор необходимых заголовков:
public function show() {

if(view()->exists('default.about')) {
$view = view('default.about')->withTitle('Hello World')->render();
return (new Response($view))->header('Content-Type', 'newType');
}
abort(404);
}
}

Мы можем формировать собственные наборы заголовков и вызывать метод header сколько угодно раз.

public function show() {

if(view()->exists('default.about')) {
$view = view('default.about')->withTitle('Hello World')->render();
return (new Response($view))
->header('Content-Type', 'newType')
->header('Header-One', 'header')
;

}
abort(404);
}
}

Ответ можно сформировать, используя функцию-хелпер response. Работа этой функции аналогична использованию конструктора класса Response.

public function show() {

if(view()->exists('default.about')) {
$view = view('default.about')->withTitle('Hello World')->render();
return (new Response($view))
->header('Content-Type', 'newType')
->header('Header-One', 'header')
;
return response($view)->header('Content-Type', 'newType')
->header('Header-One', 'header')
;


}
abort(404);
}

Откроем файл: vendor\laravel\framework\src\Illuminate\Foundation\helpers.php

function response($content = '', $status = 200, array $headers = [])
{
$factory = app(ResponseFactory::class); // возвращает реализацию интерефейса, т.е объект класса ResponseFactory

if (func_num_args() === 0) {
return $factory;
}

return $factory->make($content, $status, $headers);
}

В файле \vendor\laravel\framework\src\Illuminate\Contracts\Routing\ResponseFactory.php
описан класс ResponseFactory. Это общий класс для формирования дальнейших ответов.

Вернем ответ в виде JSON-строки:

public function show() {

if(view()->exists('default.about')) {
$view = view('default.about')->withTitle('Hello World')->render();
return response()->json(['name'=>'Hello', 'name1'=>'Hello1']);
}
abort(404);
}

Набираем: http://tlaravel.loc/about
Возвращает:
name
"Hello"
name1
"Hello1"

Вызовем метод view() без параметров. Он возвращает объект класса Response, но для конкретного вида.
public function show() {

if(view()->exists('default.about')) {
$view = view('default.about')->withTitle('Hello World')->render();
return response()->view('default.about', ['title'=>'hello world']);
}
abort(404);
}
}

Отдадим на скачивание файл robots.txt из каталога public

public function show() {

if(view()->exists('default.about')) {
$view = view('default.about')->withTitle('Hello World')->render();
return response()->download('robots.txt', 'mytext.txt'); // mytext.txt - имя файла, под которым он будет отдаваться на скачку
}
abort(404);
}

Обратимся: http://tlaravel.loc/about
Начнется скачивание файла.

Для более удобной передачи заголовков используется метод withHeaders()
public function show() {

if(view()->exists('default.about')) {
$view = view('default.about')->withTitle('Hello World')->render();
return response($view)->withHeaders([
'headerOne'=>'hello',
'headerTwo'=>'hi',
]);
}
abort(404);
}

Редирект — тоже определенный ответ.

public function show() {

if(view()->exists('default.about')) {
$view = view('default.about')->withTitle('Hello World')->render();
return redirect('/');
}
abort(404);
}
Обратимся: http://tlaravel.loc/about
Перенаправляет на главную страницу.

public function show() {

if(view()->exists('default.about')) {
$view = view('default.about')->withTitle('Hello World')->render();
return redirect('/articles');
}
abort(404);
}
Обратимся: http://tlaravel.loc/about
Перенаправляет на http://tlaravel.loc/articles

В файле vendor\laravel\framework\src\Illuminate\Http\RedirectResponse.php
описан класс RedirectResponse, который возвращается, если мы вызываем на исполнение метод redirect.

Родительский класс: \vendor\symfony\http-foundation\RedirectResponse.php

Можно вернуть объект класса RedirectResponse. Для этого нужно прописать пространство имен.

<?php

namespace App\Http\Controllers\Admin;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

use Illuminate\Http\Response; // предоставим доступ к классу Response. Если мы не добавим эту строку, будет сгенерировнно сключение.
use Illuminate\Http\RedirectResponse; // здесь прописываем пространство имен

class AboutController extends Controller
{
public function show() {

if(view()->exists('default.about')) {
$view = view('default.about')->withTitle('Hello World')->render();
return new RedirectResponse('articles');
}
abort(404);
}
}

Этот метод не очень удобен. Используем статический метод create из родительского класса.
public function show() {

if(view()->exists('default.about')) {
$view = view('default.about')->withTitle('Hello World')->render();
return RedirectResponse::create('articles');
}
abort(404);
}

Перенаправление на предыдущую страницу.
В файле vendor\laravel\framework\src\Illuminate\Foundation\helpers.php ищем метод back()

Можно осуществлять редирект на определенный маршрут:

public function show() {

if(view()->exists('default.about')) {
$view = view('default.about')->withTitle('Hello World')->render();
return redirect()->route('home');
}
abort(404);
}

Можно осуществлять редирект на метод контроллера:
public function show() {

if(view()->exists('default.about')) {
$view = view('default.about')->withTitle('Hello World')->render();
return redirect()->action('Admin\ContactController@show');
}
abort(404);
}

Редирект и запись параметров в сессию
public function show() {

if(view()->exists('default.about')) {
$view = view('default.about')->withTitle('Hello World')->render();
return redirect('/articles')->with('param1','Hello'); // параметр param1 запишется в сессию
}
abort(404);
}


Создадим свой пользовательский ответ.
В файле app\Providers\AppServiceProvider.php есть метод boot(), где мы можем создать свой собственный макет.
Напишем в начале файла:
use Response;

public function boot()
{
//
Response::macro('myRes', function($value) {
return Response::make($value);
});
}

Идем в AboutController.php
public function show() {

if(view()->exists('default.about')) {
$view = view('default.about')->withTitle('Hello World')->render();
return response()->myRes('Hello world');
}
abort(404);
}

Возвращается: Hello world

На практике мы можем заготовить свои заголовки и передавать их.


Метод macro() позволяет зарегистрировать свой ответ, к которому мы можем обращаться для формирования данных.

Заметка: в файле config\app.php описаны псевдонимы для определенных глобальных классов. Псевдоним Responce создается для такого фасада: 'Response' => Illuminate\Support\Facades\Response::class,

Фасады - классы-посредники, которые предоставляют доступ к определенным главным классам фреймворка.

Перейдем в фасад Response по адресу: vendor\laravel\framework\src\Illuminate\Support\Facades\Response.php

Все из каталога Contracts — интерфейсы.



Комментариев нет:

Отправить комментарий

Materialize-css. Футер

Сделаем футер и прижмем к низу страницы. Документация: https://materializecss.com/footer.html