В конце второй части этой серии я хотел бы поговорить о пользе использования компонентов Symfony2 – это совместимость между всеми фреймворками и приложениями, которые тоже их используют. Давайте сделаем большой шаг навстречу этой цели. Реализуем в нашем фреймворке HttpKernelInterface:

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

Обновим наш фремворк так, чтобы он реализовывал этот интерфейс:

Даже если изменения выглядят тривиальными это приносит нам много хорошего! Давайте поговорим об одной из этих классных вещей: прозрачная поддержка HTTP caching.

Класс HttpCache реализует полнофункциональный обратный прокси-сервер, написанный на PHP; он реализует HttpKernelInterface и обертывается другим HttpKernelInterface:

Все! Теперь наш фреймворд поддерживает HTTP кэширование. Некруто ли?

Настройка кэширования производится посредством HTTP заголовков. Например, чтобы ответ закешировался на 10 секунд, необходимо использовать метод Response::setTtl():

Если вы, как я, запустили ваш фреймворк через командную строку, эмитируя запрос Request::create(‘/is_leap_year/2012’, вы можете легко дебажить экземпляр Response, через его строковое представление (echo $response;); эта команда выведет все заголовки вместе с контентом ответа.

Чтобы кэш заработал вы должны создать папку cache и дать ей права на запись сервером ( я давал 777 )

Если папки не будет, то PHP  вам сообщит, но если он не сможет туда записать, то он вам об этом не скажет и вы будете долго искать проблему.

Чтобы убедиться в том, что кэширование работает, добавим случайное число в наш ответ и проверим, что не меняется в течении 10 секунд:

При развертывании ваше продакш окружения, продолжайте использовать обратный прокси Symfony2 (отлично подходит для хостинга) или даже лучше, перейдите на более эффективный проски, например Varnish.

Использование HTTP заголовков для управления кэшем вашего приложения очень мощно и позволяет вам тонко настроить вашу стратегию кэширования, т.к. вы можете настроить спецификацию проверки или истечения срока. Если вы плаваете в этой теме, то я вам настоятельно рекомендую прочитать клаву из документации Symfony2  HTTP caching.

Класс Response содержит кучу других методов, позволяющий настроить HTTP кэш. Одной из наиболее мощных является setCache() как абстрактная для большинства стратегий кэширования:

Когда вы используете условное кэширование, метод isNotModified() позволяет вам быстрее отравить ответ:

HTTP кэширование это круто, но что если вы не можете закэшировать страницу целиком? Что если вы кешируете все, кроме сайдбара, который формируется динамически? Edge Side Includes (ESI) – вот оно спасение! Вместо того чтобы генерировать станицу целиком, ESI позволяет вам отметить части страницы, как суб-запросы:

Для поддержки ESI тэгов HttpCache, вы должны передать экземпляр ESI класса. ESI класс автоматически распарсит ESI тэги, сделает суб-запросы и сконвертирует их в соотвествующий контент:

Для работы с ESI вам необходимо использовать обратное прокси, который поддерживает. Varnish – лучшая альтернатива и это открытое программное обеспечение.

Когда вы используете сложную стратегию кэширования и/или много ESI тэгов, может быть трудно понять почему и где ресурсы должны кэшироваться, а где нет. Чтобы было проще дебажить вы можете включить debug mode:

Debug mode добавляет заголовок X-Symfony-Cache к каждому ответу, который описывает слой кэша:

HttpCache имеет кучу функций таких как stale-while-revalidate и stale-if-error.

С добавлением единственного интерфейса, наш фреймворк теперь может использовать кучу фич, реализованных в компоненте HttpKernel; HTTP кэширование только одно из них, но одно из самых важных, которое позволит вашему приложению летать!