Ошибки, сложный материал, вопросы >
Нашли опечатку или неточность?

Выделите текст, нажмите ctrl + enter и отправьте его нам. В течение нескольких дней мы исправим ошибку или улучшим формулировку.

Что-то не получается или материал кажется сложным?

Загляните в раздел «Обсуждение»:

  • задайте вопрос нашим менторам. Вы быстрее справитесь с трудностями и прокачаете навык постановки правильных вопросов, что пригодится и в учёбе, и в работе программистом;
  • расскажите о своих впечатлениях. Если курс слишком сложный, подробный отзыв поможет нам сделать его лучше;
  • изучите вопросы других учеников и ответы на них. Это база знаний, которой можно и нужно пользоваться.
Об обучении на Хекслете

Стандарт PSR7

Архитектура любого серверного веб-фреймворка, опирается на особенности протокола HTTP. В первую очередь сюда входят понятия запроса (request) и ответа (response). Это значит что каждому веб-фреймворку, так или иначе, приходится реализовывать эти объекты у себя, повторяя то что уже было сделано в других местах.

Чтобы избежать такой ситуации, был разработан стандарт PSR7. Цель PSR-7 предоставить общий набор интерфейсов для фреймворков, чтобы последние могли использовать одинаковые абстракции. Это позволит разработчикам писать переиспользуемый, независимый от фреймворка код. Сам стандарт довольно объёмный и не имеет смысла его дублировать. Здесь мы поговорим только о ключевых особенностях.

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

Объекты запроса и ответа во фреймворке Slim имеют интерфейс соответствующий стандарту PSR-7. Пример на главной странице фреймворка как раз демонстрирует это:

<?php

use Slim\Factory\AppFactory;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;

require 'vendor/autoload.php';

$app = AppFactory::create();
$app->get('/hello/{name}', function (Request $request, Response $response, array $args) {
    $name = $args['name'];
    // Эта функция write возвращает количество переданных байт
    $response->getBody()->write("Hello, {$name}");
    return $response;
});
$app->run();

getBody() возвращает специальный объект-поток (stream). Этот объект можно изменять, записывая туда данные.

Интерфейсы, описанные в PSR7, эмулируют работу HTTP. С помощью их методов можно как извлечь любую информацию из запроса, так и создать любой ответ.

<?php

// Возвращает значение заголовка Host
$request->getHeader('Host');

// Проверяет был ли указан заголовок
$request->hasHeader('Accept');

Эти методы работают не только для запроса, но и для ответа. Дело в том, что оба эти интерфейса Request и Response, имеют общую часть, которая называется Message, другими словами, многие методы повторяются и одинаково работают в каждом из этих объектов.

Названия заголовков в PSR-7, как и в самом HTTP регистронезависимы. В то же время в самом PHP, заголовки всегда переводятся в верхний регистр и хранятся в массиве $_SERVER с префиксом HTTP_.

<?php

// Возвращает массив заголовков, в котором значения заголовков разделены по элементам массива
foreach ($request->getHeaders() as $name => $values) {
    echo $name . ': ' . implode(', ', $values);
}

Response

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

<?php

// Статус ответа. По умолчанию 200.
$status = $response->getStatusCode();

А вот с изменением все не так просто. Главная отличительная черта этого интерфейса в том, что он построен в иммутабельном (неизменяемом) стиле и реализует текучий интерфейс (fluent interface). Ответ невозможно "изменить" (ниже будет одно исключение). Вместо этого, всегда возвращается новый объект.

<?php

// response не меняется!
$newResponse = $response->withStatus(302);
$newResponse === $response; // false

По этой причине, во фреймворках, поддерживающих стандарт PSR-7, обработчик запроса всегда должен вернуть объект ответа, только в этом случае фреймворк узнает о том, как надо ответить на запрос.

<?php

$app->get('/something', function (Response $response) {
    return $response->withStatus(500)
        ->withHeader('Content-Type', 'text/html');
});

Единственная часть в Response, которую можно менять – тело ответа. Это связано с техническими особенностями работы потоков в самом PHP. Подробнее об этом можно прочитать в документации

<?php

$app->get('/something', function (Response $response) {
    $response->getBody()->write('То что отправится пользователю в теле ответа');
    // Ответ все равно надо вернуть!
    return $response;
});

Несмотря на все это, PSR7 достаточно низкоуровневый стандарт. Он не ставил перед собой целью сделать работу с объектами ответа и запроса максимально удобной и простой. Задача была в эмуляции поведения HTTP. Поэтому помимо реализации стандартных интерфейсов, многие фреймворки создают дополнительные обертки поверх PSR7. Эти обертки уже дают много прикладных полезных методов. Одну из таких оберток мы начали использовать с самого начала: Slim-Http. Вот лишь небольшой список полезных функций этой библиотеки которые мы либо использовали, либо будем использовать:

  • Response::write($data) – изменяет ответ
  • Response::withRedirect($url, $status)
  • ServerRequest::getParam($key, $default)
  • ServerRequest::getParsedBody()

Самостоятельная работа

  1. Реализуйте код ошибки 404 в случае если обращение идет к несуществующему пользователю. Существование пользователя проверяйте через файл созданный в предыдущем уроке, который содержит всех пользователей.

Дополнительные материалы

  1. PSR7

<span class="translation_missing" title="translation missing: ru.web.courses.lessons.mentors.mentor_avatars">Mentor Avatars</span>

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят менторы из команды Хекслета или другие студенты.

Для полного доступа к курсу нужна профессиональная подписка

Профессиональная подписка откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, даст возможность обращаться за помощью к менторам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
115
курсов
892
упражнения
2241
час теории
3196
тестов

Зарегистрироваться

или войти в аккаунт

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.

  • 115 курсов, 2000+ часов теории
  • 800 практических заданий в браузере
  • 250 000 студентов

Отправляя форму, вы соглашаетесь c «Политикой конфиденциальности» и «Условиями оказания услуг».

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Rambler
Логотип компании Bookmate
Логотип компании Botmother

Есть вопрос или хотите участвовать в обсуждении?

Зарегистрируйтесь или войдите в свой аккаунт

Отправляя форму, вы соглашаетесь c «Политикой конфиденциальности» и «Условиями оказания услуг».