Роутинг для PSR 7 Response/Request. Часть 1: Обзор

Сухая выжимка из видео Дмитрия Елисеева PSR-7 фреймворк 2/6: Контроллеры и маршрутизация.

Вводные данные

У нас уже есть входная точка для нашего приложения и подключена библиотека для работы с HTTP PSR 7  — в примерах будет Zend Diactoros.

В итоге наш index.php выглядит так:


<\?php

use Zend\Diactoros\Response\HtmlResponse;
use Zend\Diactoros\Response\SapiEmitter;
use Zend\Diactoros\ServerRequestFactory;

chdir(dirname(__DIR__));
require 'vendor/autoload.php';

### Initialization
$request = ServerRequestFactory::fromGlobals();

### Action
$name = $request->getQueryParams()['name'] ?? 'Guest';
$response = new HtmlResponse('Hello, ' . $name . '!');

### Postprocessing
$response = $response->withHeader('X-Developer', 'maksfedorov.ru');

### Sending
$emitter = new SapiEmitter();
$emitter->emit($response);


По коду:

  1. Подключаем фабрику Zend Diactoros, которая конвертирует глобальные переменные в объекты Request и Response
  2. Создаем объект Response и передаем в него значение GET параметра name или строку ’Guest’
  3. Добавляем свой пользовательский заголовок к объекту Response
  4. Отправляем на вывод, добавляя код ответа и тип контента

Первый роутинг

Получим наш пользовательский путь (после исполняющего скрипта, до параметров). На основе этого пути зададим свой объект Response и передадим в каждый соответствующий контент.

Помимо простых путей, мы можем добавить сюда более гибкие пути, например для блога в виде JSON:


<\?php

### Action
$path = $request->getUri()->getPath();

if ($path === '/') {
    $name = $request->getQueryParams()['name'] ?? 'Guest';
    $response = new HtmlResponse('Hello, ' . $name . '!');
} elseif ($path === '/about') {
    $response = new HtmlResponse('I am a simple site');
} else {
    $response = new HtmlResponse('Undefined page', 404);
}

# ...


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


<\?php



Это и есть простейший роутинг, но как понимаете — если контент будет сколь заметным или путей будет много — работать с таким кодом будет крайне не удобно.

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

Оптимизация

Чтобы в условиях для каждого роута наши переменные не зассоряли наш эфир и глобальные переменные — поместим этот код в анонимные функции, присвоим их результат переменной $action и после условия выведем результат подходящей условию переменной:

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

Но мы можем воспользоваться методом withAttribute() объекта Request, тем самым изменяя сам объект Request, который мы и передаем в анонимную функцию, в итоге выглядет это так:


<\?php



ADR (Action Domain Response)

Action Domain Response — частный и упрощенный случай MVC.

Суть этого подхода для нас — нам нужно сделать систему маршрутизации, при которой в зависимости от разных адресов мы возвращаем нужную анонимную функцию.

Простейший вариант:


<\?php



Но для учета HTTP методов (например для REST API) это будет иметь такой вид:


<\?php



Теперь мы получили представление о том, что нам нужно получить и как это должно работать, в следующей части разберем принцип построения системы маршрутизации перейти к созданию маршрутизации→

Поделиться
Отправить
Популярное