Возврат ответов

Одной из частей работы HTTP-протокола является возвращение ответа клиенту. В Phalcon существует компонент Phalcon\Http\Response для реализации этой задачи. Чаще всего HTTP-ответ состоит из заголовков и тела ответа. Далее приведен пример базового использования:

<?php

use Phalcon\Http\Response;

// Получение экземпляра Response
$response = new Response();

// Установка кода статуса
$response->setStatusCode(404, 'Not Found');

// Установка содержимого ответа
$response->setContent("Сожалеем, но страница не существует");

// Отправка ответа клиенту
$response->send();

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

<?php

use Phalcon\Http\Response;
use Phalcon\Mvc\Controller;

class FeedController extends Controller
{
    public function getAction()
    {
        // Получение экземпляра Response
        $response = new Response();

        $feed = // ... тут данные

        // Установка содержимого ответа
        $response->setContent(
            $feed->asString()
        );

        // Возврат Response ответа
        return $response;
    }
}

Работа с заголовками

Headers are an important part of the HTTP response. It contains useful information about the response state like the HTTP status, type of response and much more.

Указывать заголовки можно следующим образом:

<?php

// Установка по имени
$response->setHeader('Content-Type', 'application/pdf');
$response->setHeader('Content-Disposition', "attachment; filename='downloaded.pdf'");

// Установка напрямую
$response->setRawHeader('HTTP/1.1 200 OK');

Корзина Phalcon\Http\Response\Headers внутренне управляет заголовками. Этот класс извлекает заголовки перед отправкой его клиенту:

<?php

// Получение всех заголовков
$headers = $response->getHeaders();

// Получение заголовка по имени
$contentType = $headers->get('Content-Type');

Создание перенаправлений

С помощью Phalcon\Http\Response вы можете выполнять перенаправления HTTP:

<?php

// Перенаправление на URL по умолчанию
$response->redirect();

// Перенаправление на внутренний URI
$response->redirect('posts/index');

// Перенаправление на внешний URL
$response->redirect('http://en.wikipedia.org', true);

// Перенаправление со специальным HTTP-кодом 
$response->redirect('http://www.example.com/new-location', true, 301);

Все внутренние URI генерируются с помощью сервиса url (по умолчанию Phalcon\Mvc\Url). Этот пример демонстрирует возможность перенаправления с использованием маршрута (роута), который вы задали в своем приложении:

<?php

// Перенаправление основаное на имени маршрута
return $response->redirect(
    [
        'for'        => 'index-lang',
        'lang'       => 'jp',
        'controller' => 'index',
    ]
);

Обратите внимание, что перенаправление не отключает компонент представления, таким образом, если имеется представление, связанное с текущим действием, оно в любом случае будет выполняться. Вы можете отключить представление из контроллера, выполнив $this->view->disable().

HTTP-кэш

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

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

  • Expires: Устанавливая этот заголовок в прошлое или будущее можно указывать браузеру срок жизни страницы.
  • Cache-Control: Позволяет указать сколько времени страница должна считаться для браузера актуальной.
  • Last-Modified: Указывает браузеру когда было последнее изменение страницы, что позволяет избежать повторной загрузки страницы.
  • ETag: Представляет собой уникальный идентификатор, который должен быть сформирован с учетом времени изменения текущей страницы.

Истечение времени кэша (Expires)

Указание срока жизни является одним из наиболее удобных и эффективных способов кэширования страниц на стороне клиента (браузера). Начиная с текущей даты мы добавляем некоторое количество времени, в течение которого страница будет храниться в кэше браузера. Это укажет браузеру сохранять страницу в кэше пока этот срок не истечет и не обращаться за ней к серверу:

<?php

$expiryDate = new DateTime();
$expiryDate->modify('+2 months');

$response->setExpires($expiryDate);

Ответ в компоненте Response автоматически преобразует дату для временной зоны GMT, именно так как ожидается в заголовке Expires.

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

<?php

$expiryDate = new DateTime();
$expiryDate->modify('-10 minutes');

$response->setExpires($expiryDate);

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

Cache-Control

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

<?php

// Кэшировать страницу один день, начиная с текущего момента
$response->setHeader('Cache-Control', 'max-age=86400');

Противоположный эффект (для запрета кэширования страницы) организуется следующим образом:

<?php

// Никогда не кэшировать обслуживаемую страницу
$response->setHeader('Cache-Control', 'private, max-age=0, must-revalidate');

E-Tag

Заголовок entity-tag или кратко E-tag позволяет браузеру понять, была ли изменена страница между двумя запросами. Идентификатор должен рассчитываться таким образом, что бы измениться если изменено содержимое страницы:

<?php

// Формирование значения E-Tag основанное на последнем времени изменения новости
$mostRecentDate = News::maximum(
    [
        'column' => 'created_at'
    ]
);

$eTag = md5($mostRecentDate);

// Отправка E-Tag
$response->setHeader('E-Tag', $eTag);