Как очистить кеш Symfony

Обновлено: 04.07.2024

Сегодня я покажу вам компонент Symfony Cache, простой способ добавить кэширование в ваши PHP-приложения. Это помогает повысить общую производительность приложения за счет сокращения времени загрузки страницы.

Компонент Symfony Cache

Компонент Symfony Cache позволяет настроить кэширование в ваших PHP-приложениях. Сам компонент очень прост в установке и настройке и позволяет быстро приступить к работе. Кроме того, он предоставляет на выбор множество адаптеров, как показано в следующем списке:

  • адаптер базы данных
  • адаптер файловой системы
  • адаптер memcached
  • Адаптер Redis
  • APCu-адаптер
  • и многое другое

Когда дело доходит до кэширования с использованием компонента Symfony Cache, вам следует ознакомиться с парой терминов.

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

В этой статье мы рассмотрим, как вы можете раскрыть всю мощь компонента Symfony Cache. Как обычно, мы начнем с установки и настройки, а затем перейдем к рассмотрению нескольких реальных примеров во второй половине статьи.

Установка и настройка

В этом разделе мы установим компонент Cache. Я предполагаю, что вы уже установили Composer в своей системе — он понадобится вам для установки компонента Cache, доступного на Packagist.

После того как вы установили Composer, установите компонент Cache, используя следующую команду.

Это должно было создать файл composer.json, который должен выглядеть следующим образом:

Это все для установки, но как вы должны добавить его в свое приложение? Нужно просто включить файл autoload.php, созданный Composer, в ваше приложение, как показано в следующем фрагменте кода.

Реальный пример

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

Для начала создадим файл index.php со следующим содержимым.

Давайте рассмотрим основные части файла index.php, чтобы понять их назначение.

Создать пул кеша

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

Вы можете указать три необязательных аргумента для объекта FilesystemAdapter:

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

Как сохранить строковые значения

Поскольку мы уже создали пул кеша, мы можем использовать его для хранения элементов кеша.

Во-первых, мы используем метод getItem для получения элемента кеша с помощью ключа demo_string. Затем мы используем метод isHit, чтобы проверить, присутствует ли искомое значение в элементе кэша $demoString .

Поскольку мы впервые извлекаем элемент кеша demo_string, метод isHit должен возвращать false . Затем мы используем метод set объекта $demoString для установки значения кэша. Наконец, мы сохраняем элемент кеша $demoString в пул кеша $cachePool, используя метод сохранения.

Теперь, когда мы сохранили элемент в кеше, давайте посмотрим, как извлечь его из кеша.

Здесь мы используем метод hasItem для проверки существования элемента кеша в пуле кеша перед его извлечением.

Далее посмотрим, как удалить все элементы кеша из пула кеша:

Как сохранить значения массива

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

Как видите, мы можем просто установить элемент кеша со значением массива, точно так же, как мы сделали это для строки.

Далее посмотрим, как удалить конкретный элемент кеша из пула кеша.

Здесь мы используем метод deleteItem для удаления элемента demo_array из пула кеша.

Как установить дату истечения срока действия для кэшированных элементов

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

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

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

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

Протестируйте его, чтобы увидеть, как он работает!

Заключение

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

Не стесняйтесь выражать свои мысли и вопросы, используя форму ниже.

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

12.2.1. Очистка всего кеша

Задача очистки кеша командной строки symfony стирает кеш (HTML, конфигурацию и кеш i18n). Вы можете передать ему аргументы, чтобы стереть только подмножество кэша, как показано в листинге 12-8. Не забывайте вызывать его только из корня проекта Symfony.

Листинг 12-8. Очистка кэша

12.2.2. Очистка отдельных частей кэша

При обновлении базы данных необходимо очистить кеш действий, связанных с измененными данными. Вы можете очистить весь кеш, но это будет пустой тратой всех существующих кешированных действий, не связанных с изменением модели. Здесь применяется метод remove() объекта sfViewCacheManager. Он ожидает внутренний URI в качестве аргумента (тот же аргумент, который вы бы предоставили для link_to() ) и удаляет связанный кеш действий.

Например, представьте, что действие обновления пользовательского модуля изменяет столбцы объекта User. Необходимо очистить кешированные версии списка и показать действия, иначе будут отображаться старые версии, содержащие ошибочные данные. Для этого используйте метод remove(), как показано в листинге 12-9.

Листинг 12-9. Очистка кэша для заданного действия в modules/user/actions/actions.class.php

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

Теоретически вы можете удалить кэшированный фрагмент с помощью метода remove(), если вы знаете значение хэша параметров, используемого для его идентификации, но это практически невозможно. К счастью, если вы добавите параметр sf_cache_key к вспомогательному вызову include_partial(), вы сможете идентифицировать партиал в кеше с чем-то, что вам известно. Как вы можете видеть в листинге 12-10, очистка одного кэшированного партиала — например, очистка кэша от партиала на основе измененного пользователя — становится простой задачей.

Листинг 12-10. Частичная очистка кэша

Этот метод нельзя использовать для очистки всех вхождений партиала в кэше. Вы узнаете, как очистить их, в разделе «Очистка кэша вручную» далее в этой главе.

Чтобы очистить фрагменты шаблона, используйте тот же метод remove(). Ключ, идентифицирующий фрагмент в кеше, состоит из того же префикса sf_cache_partial, имени модуля, имени действия и sf_cache_key (уникальное имя фрагмента кеша, включенное помощником cache()). В листинге 12-11 показан пример.

Листинг 12-11. Очистка фрагментов шаблона из кэша

Выборочная очистка кеша может повредить ваш мозг Самая сложная часть работы по очистке кеша — определить, на какие действия влияет обновление данных.

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

Когда вы начинаете использовать кеш HTML, вам нужно иметь четкое представление о зависимостях между моделью и действиями, чтобы новые ошибки не появлялись из-за неправильно понятой взаимосвязи. Имейте в виду, что все действия, изменяющие модель, вероятно, должны содержать кучу вызовов метода remove(), если где-то в приложении используется кэш HTML.

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

12.2.3. Структура каталогов кэша

Кэшированные шаблоны хранятся в каталоге [HOST_NAME] (где точки заменены символами подчеркивания для совместимости с файловыми системами) в структуре каталогов, соответствующей их URL. Например, кеш шаблона страницы, вызываемой с помощью:

Не следует указывать пути к файлам непосредственно в коде. Вместо этого вы можете использовать константы пути к файлу. Например, чтобы получить абсолютный путь к каталогу template/ текущего приложения в текущей среде, используйте sfConfig::get('sf_template_cache_dir') .

Знание этой структуры каталогов поможет вам справиться с очисткой кеша вручную.

12.2.4. Очистка кеша вручную

Очистка кеша между приложениями может быть проблемой. Например, если администратор изменяет запись в таблице пользователей во внутреннем приложении, все действия, зависящие от этого пользователя во внешнем приложении, должны быть удалены из кеша. Метод remove() ожидает внутренний URI, но приложения не знают правил маршрутизации других приложений (приложения изолированы друг от друга), поэтому вы не можете использовать метод remove() для очистки кэша другого приложения.

Решение состоит в том, чтобы вручную удалить файлы из каталога cache/ в зависимости от пути к файлу. Например, если внутреннему приложению необходимо очистить кеш действия user/show во внешнем приложении для пользователя с идентификатором 12, оно может использовать следующее:

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

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

Чтобы удалить кешированный профиль пользователя с идентификатором 12 на всех языках, вы можете просто сделать это:

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

12.2.1. Очистка всего кеша

Задача cache:clear командной строки symfony стирает кеш (HTML, конфигурацию, маршрутизацию и кеш i18n). Вы можете передать ему аргументы, чтобы стереть только подмножество кэша, как показано в листинге 12-8. Не забывайте вызывать его только из корня проекта Symfony.

Листинг 12-8. Очистка кэша

12.2.2. Очистка отдельных частей кэша

При обновлении базы данных необходимо очистить кеш действий, связанных с измененными данными. Вы можете очистить весь кеш, но это будет пустой тратой всех существующих кешированных действий, не связанных с изменением модели. Здесь применяется метод remove() объекта sfViewCacheManager. Он ожидает внутренний URI в качестве аргумента (тот же аргумент, который вы бы предоставили для link_to() ) и удаляет связанный кеш действий.

Например, представьте, что действие обновления пользовательского модуля изменяет столбцы объекта User. Необходимо очистить кешированные версии списка и показать действия, иначе будут отображаться старые версии, содержащие ошибочные данные. Для этого используйте метод remove(), как показано в листинге 12-9.

Листинг 12-9. Очистка кэша для заданного действия в modules/user/actions/actions.class.php

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

Теоретически вы можете удалить кэшированный фрагмент с помощью метода remove(), если вы знаете значение хэша параметров, используемого для его идентификации, но это практически невозможно. К счастью, если вы добавите параметр sf_cache_key к вспомогательному вызову include_partial(), вы сможете идентифицировать партиал в кеше с чем-то, что вам известно.Как вы можете видеть в листинге 12-10, очистка одного кэшированного партиала — например, очистка кэша от партиала на основе измененного пользователя — становится простой задачей.

Листинг 12-10. Частичная очистка кэша

Чтобы очистить фрагменты шаблона, используйте тот же метод remove(). Ключ, идентифицирующий фрагмент в кеше, состоит из того же префикса sf_cache_partial, имени модуля, имени действия и sf_cache_key (уникальное имя фрагмента кеша, включенное помощником cache()). В листинге 12-11 показан пример.

Листинг 12-11. Очистка фрагментов шаблона из кэша

Выборочная очистка кеша может повредить ваш мозг Самая сложная часть работы по очистке кеша — определить, на какие действия влияет обновление данных.

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

Когда вы начинаете использовать кеш HTML, вам нужно иметь четкое представление о зависимостях между моделью и действиями, чтобы новые ошибки не появлялись из-за неправильно понятой взаимосвязи. Имейте в виду, что все действия, изменяющие модель, вероятно, должны содержать кучу вызовов метода remove(), если где-то в приложении используется кэш HTML.

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

12.2.3. Очистка нескольких частей кэша одновременно (новое в symfony 1.1)

Метод remove() принимает ключи с подстановочными знаками. Он позволяет удалить несколько частей кэша одним вызовом. Вы можете сделать, например:

Другой хороший пример – приложения, работающие с несколькими языками, когда код языка отображается во всех URL-адресах. URL-адрес страницы профиля пользователя должен выглядеть следующим образом:

Чтобы удалить кешированный профиль пользователя с идентификатором 12 на всех языках, вы можете просто вызвать:

Это также работает для частичных:

Метод remove() работает со всеми стратегиями кэширования, которые можно определить в файле factory.yml (не только sfFileCache, но и sfAPCCache, sfEAcceleratorCache, sfMemcacheCache, sfSQLiteCache и sfXCacheCache).

12.2.4. Очистка кеша между приложениями (новое в symfony 1.1)

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

Решение состоит в том, чтобы вручную инициализировать объект sfCache с теми же настройками, что и у внешнего диспетчера кеша. К счастью, все классы кеша в symfony предоставляют метод removePattern, обеспечивающий тот же сервис, что и remove менеджера кеша представлений.

Например, если внутреннему приложению необходимо очистить кеш действия пользователя/показать во внешнем приложении для пользователя с идентификатором 12 , оно может использовать следующее:

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

Возможно, ваш браузер не поддерживает кодек H264. Если вы используете Linux, попробуйте другой браузер или попробуйте установить пакеты gstreamer0.10-ffmpeg gstreamer0.10-plugins-good.

Спасибо! Это избавляет нас от необходимости использовать Flash или кодировать видео в нескольких форматах. И это давайте вернемся к созданию большего количества видео :). Но, как всегда, пожалуйста, напишите нам.

Для просмотра этого видео включите JavaScript и рассмотрите возможность перехода на веб-браузер, поддерживающий видео в формате HTML5

Синтаксический анализ уценки для каждого запроса сделает наше приложение излишне медленным. Так. давайте кешируем это! Конечно, кэширование чего-либо — это «работа». и, как я постоянно говорю, вся «работа» в Symfony выполняется сервисом.

Поиск службы кэширования

Давайте воспользуемся нашей надежной командой debug:autowiring, чтобы узнать, есть ли какие-либо службы, содержащие слово "кеш". И да, вы можете также просто найти это в Google и прочитать документацию: мы учимся делать вещи сложным способом, чтобы сделать вас опасными:

И. прохладно! В нашем приложении уже есть система кэширования! Очевидно, есть несколько сервисов на выбор. Но, как мы говорили ранее, синий текст — это «id» сервиса.Таким образом, 3 из этих подсказок типа — это разные способы получения одного и того же объекта службы, один из них на самом деле является регистратором, а не кешем, а последний — TagAwareCacheInterface — является другой объект кеша: более мощный, если вы хотите сделать что-то, называемое «аннулированием на основе тегов». Если вы не понимаете, о чем я говорю, не волнуйтесь.

Для нас мы будем использовать обычную службу кеша. а CacheInterface — моя любимая подсказка типа, потому что с его методами проще всего работать.

Использование службы кэширования

Вернитесь к контроллеру и добавьте еще один аргумент: CacheInterface — тот, что из Symfony\Contracts — и назовите его $cache :

. строки 1-8
use Symfony \ Contracts \ Cache \ CacheInterface ;
. строки 10-11
класс QuestionController расширяет AbstractController
. строки 14 - 31
общедоступная функция show ($slug, MarkdownParserInterface $markdownParser, CacheInterface $cache)
. строки 34–49
>
>

Этот объект делает кеширование интересным. Вот как это работает: скажем $parsedQuestionText = $cache->get() . Первый аргумент — это уникальный ключ кеша. Давайте передадим markdown_ , а затем md5() для $questionText . Это даст каждому уникальному тексту уценки собственный уникальный ключ.

Теперь вы можете подумать:

Привет, Райан! Разве вам не нужно сначала проверить, находится ли этот ключ уже в кеше? Что-то вроде if ($cache->has()) ?

Да. но нет. Этот объект работает немного иначе: функция get() имеет аргумент второй, функцию обратного вызова. Вот идея: если этот ключ находится уже в кеше, метод get() немедленно вернет значение. Но если это нет - это "промах" кеша - тогда он вызовет нашу функцию, мы вернем проанализированный HTML, и он сохранит в кеше.

Скопируйте код преобразования уценки, вставьте его в обратный вызов и верните. Хм, у нас есть две неопределенные переменные, потому что нам нужно поместить их в область действия функции. Сделайте это, добавив use ($questionText, $markdownParser):

. строки 1–11
класс QuestionController расширяет AbstractController
. строки 14 - 31
общедоступная функция show ($slug, MarkdownParserInterface $markdownParser, CacheInterface $cache)
. строки 34–40
$parsedQuestionText = $cache->get( 'markdown_' .md5($questionText), function () use ($questionText, $markdownParser)
return $markdownParser->transformMarkdown($questionText);
>);
. строки 44 - 49
>
>

Это счастье! Я счастлив! Давай попробуем! Переместите и обновите. Ok. он не сломался. Это кешировалось? На панели инструментов веб-отладки впервые впервые рядом со значком кеша — этими тремя маленькими прямоугольниками — стоит цифра «1». Он говорит: кеш достигает 0, кеш записывает 1. Щелкните правой кнопкой мыши и откройте профайлер в новой вкладке.

Круто! В cache.app — это «идентификатор» службы кеша — он показывает один вызов get() для некоторого ключа markdown_. Это был "промах" кеша, потому что его еще не было в кеше. Закройте это, затем обновите снова. На этот раз на панели инструментов веб-отладки. да! У нас 1 попадание в кеш! Он живой!

Где хранится кэш?

О, и если вам интересно, где хранится кеш, ответ таков: в файловой системе - в каталоге var/cache/dev/pools/. Мы поговорим об этом чуть позже.

В контроллере подправьте наш вопрос - как насчет некоторых звездочек вокруг "мыслей":

. строки 1–11
класс QuestionController расширяет AbstractController
. строки 14 - 31
общедоступная функция show ($slug, MarkdownParserInterface $markdownParser, CacheInterface $cache)
. строки 34 - 38
$questionText = 'Меня превратили в кошку, есть *мысли* о том, как повернуть назад? Несмотря на то, что я **милый**, мне на самом деле наплевать на кошачью еду». ;
. строки 40 - 49
>
>

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

Итак, система кэширования работает и хранит данные в каталоге var/cache/dev/pools/. Но. что оставляет меня с вопросом. Иметь эти «инструменты» — эти сервисы — автоматически доступны замечательно. Мы быстро делаем много работы.

Но поскольку что-то еще создает экземпляры этих объектов, мы фактически не имеем никакого контроля над ними. Например, что если вместо кэширования в файловой системе я хочу кэшировать в Redis или APCu? Как мы можем сделать это? В более общем смысле, как мы можем контролировать поведение сервисов, предоставляемых нам пакетами.

Читайте также: