Кэширование данных заключается в сохранении некоторой переменной PHP в кэше и её последующем извлечении. Оно является основой для расширенных возможностей, таких как кэширование запросов и кэширование страниц.
Приведённый ниже код является типичным случаем кэширования данных, где $cache
указывает на компонент кэширования:
// Пробуем извлечь $data из кэша.
$data = $cache->get($key);
if ($data === false) {
// $data нет в кэше, вычисляем заново
$data = $this->calculateSomething();
// Сохраняем значение $data в кэше. Данные можно получить в следующий раз.
$cache->set($key, $data);
}
// Значение $data доступно здесь.
Начиная с версии 2.0.11, компонент кэширования предоставляет метод getOrSet(), который упрощает код при получении, вычислении и сохранении данных. Приведённый ниже код делает в точности то же самое, что и код в предыдущем примере:
$data = $cache->getOrSet($key, function () {
return $this->calculateSomething();
});
Если в кэше есть данные по ключу $key
, они будут сразу возвращены.
Иначе, будет вызвана переданная анонимная функция, вычисляющая значение, которое будет сохранено в кэш и возвращено
из метода.
В случае, когда анонимной функции требуются данные из внешней области видимости, можно передать их с помощью
оператора use
. Например:
$user_id = 42;
$data = $cache->getOrSet($key, function () use ($user_id) {
return $this->calculateSomething($user_id);
});
Примечание: В getOrSet() можно передать срок действия и зависимости кэша. Прочтите Срок действия кэша и Зависимости кеша чтобы узнать больше.
Кэширование данных опирается на компоненты кэширования, которые представляют различные хранилища, такие как память, файлы и базы данных.
Кэш-компоненты, как правило, зарегистрированы в качестве компонентов приложения, так что их можно настраивать и обращаться к ним глобально. Следующий код показывает, как настроить компонент приложения cache
для использования Memcached с двумя серверами:
'components' => [
'cache' => [
'class' => 'yii\caching\MemCache',
'servers' => [
[
'host' => 'server1',
'port' => 11211,
'weight' => 100,
],
[
'host' => 'server2',
'port' => 11211,
'weight' => 50,
],
],
],
],
Вы можете получить доступ к компоненту кэша, используя выражение Yii::$app->cache
.
Поскольку все компоненты кэша поддерживают единый API-интерфейс - вы можете менять основной компонент кэша на другой через конфигурацию приложения. Код, использующий кэш, при этом не меняется. Например, можно изменить конфигурацию выше для использования APC cache следующим образом:
'components' => [
'cache' => [
'class' => 'yii\caching\ApcCache',
],
],
Подсказка: Вы можете зарегистрировать несколько кэш-компонентов приложения. Компонент с именем
cache
используется по умолчанию многими классами (например, yii\web\UrlManager).
Yii поддерживает множество хранилищ кэша:
Yii::$app->cache->get($key)
. При этом можно не беспокоиться, что Yii::$app->cache
может быть null
;Подсказка: Вы можете использовать разные способы хранения кэша в одном приложении. Общая стратегия заключается в использовании памяти под хранение небольших часто используемых данных (например, статистические данные). Для больших и реже используемых данных (например, содержимое страницы) лучше использовать файлы или базу данных.
У всех компонентов кэша имеется один базовый класс yii\caching\Cache со следующими методами:
false
будет возвращено;Примечание: Не кэшируйте непосредственно значение
false
, потому что get() используетfalse
для случая, когда данные не найдены в кэше. Вы можете обернутьfalse
в массив и закэшировать его, чтобы избежать данной проблемы.
Некоторые кэш-хранилища, например, MemCache или APC, поддерживают получение нескольких значений в пакетном режиме, что может сократить накладные расходы на получение данных. Данную возможность возможно использовать при помощи multiGet() и multiAdd(). В случае, если хранилище не поддерживает эту функцию, она будет имитироваться.
Так как yii\caching\Cache реализует ArrayAccess
- следовательно компонент кэша можно использовать как массив:
$cache['var1'] = $value1; // эквивалентно: $cache->set('var1', $value1);
$value2 = $cache['var2']; // эквивалентно: $value2 = $cache->get('var2');
Каждый элемент данных, хранящийся в кэше, идентифицируется ключом. Когда вы сохраняете элемент данных в кэше, необходимо указать для него ключ. Позже, когда вы извлекаете элемент данных из кэша, вы также должны предоставить соответствующий ключ.
Вы можете использовать строку или произвольное значение в качестве ключа кэша. Если ключ не строка, то он будет автоматически сериализован в строку.
Обычно ключ задаётся массивом всех значимых частей. Например, для хранения информации о таблице в yii\db\Schema используются следующие части для ключа:
[
__CLASS__, // Название класса схемы.
$this->db->dsn, // Данные для соединения с базой.
$this->db->username, // Логин для соединения с базой.
$name, // Название таблицы.
];
Как вы можете видеть, ключ строится так, чтобы однозначно идентифицировать данные таблицы.
Если одно хранилище кэша используется несколькими приложениями, стоит указать префикс ключа во избежание конфликтов. Сделать это можно путём настройки yii\caching\Cache::$keyPrefix:
'components' => [
'cache' => [
'class' => 'yii\caching\ApcCache',
'keyPrefix' => 'myapp', // уникальный префикс ключей кэша
],
],
Для обеспечения совместимости должны быть использованы только алфавитно-цифровые символы.
Элементы данных, хранимые в кэше, остаются там навсегда и могут быть удалены только из-за особенностей функционирования хранилища (например, место для кэширования заполнено и старые данные удаляются). Чтобы изменить этот режим, вы можете передать истечение срока действия ключа при вызове метода set(). Параметр указывает на то, сколько секунд элемент кэша может считаться актуальным. Если срок годности ключа истёк, get() вернёт false
:
// Хранить данные в кэше не более 45 секунд
$cache->set($key, $data, 45);
sleep(50);
$data = $cache->get($key);
if ($data === false) {
// срок действия истек или ключ не найден в кэше
}
Начиная с версии 2.0.11 вы можете изменить значение по умолчанию (бесконечность) для длительности кэширования задав
defaultDuration в конфигурации компонента кэша. Таким образом, можно будет
не передавать значение duration
в set() каждый раз.
В добавок к изменению срока действия ключа элемент может быть признан недействительным из-за изменения зависимостей. К примеру, yii\caching\FileDependency представляет собой зависимость от времени изменения файла. Когда это время изменяется, любые устаревшие данные, найденные в кэше, должны быть признаны недействительным, а get() в этом случае должен вернуть false
.
Зависимости кэша представлены в виде объектов потомков класса yii\caching\Dependency. Когда вы вызываете set() метод, чтобы сохранить элемент данных в кэше, вы можете передать туда зависимость.
Например:
// Создать зависимость от времени модификации файла example.txt.
$dependency = new \yii\caching\FileDependency(['fileName' => 'example.txt']);
// Данные устаревают через 30 секунд.
// Данные могут устареть и раньше, если example.txt будет изменён.
$cache->set($key, $data, 30, $dependency);
// Кэш будет проверен, если данные устарели.
// Он также будет проверен, если указанная зависимость была изменена.
// Вернется `false`, если какое-либо из этих условий выполнено.
$data = $cache->get($key);
Ниже приведен список доступных зависимостей кэша:
Кэширование запросов - это специальная функция, построенная на основе кэширования данных. Она предназначена для кэширования результатов запросов к базе данных.
Кэширование запросов требует DB connection действительный cache
компонента приложения. Предпологая, что $db
это yii\db\Connection экземпляр, простое использование запросов кэширования происходит следующим образом:
$result = $db->cache(function ($db) {
// Результат SQL запроса будет возвращен из кэша если
// кэширование запросов включено и результат запроса присутствует в кэше
return $db->createCommand('SELECT * FROM customer WHERE id=1')->queryOne();
});
Кэширование запросов может быть использовано как для DAO, так и для ActiveRecord:
$result = Customer::getDb()->cache(function ($db) {
return Customer::find()->where(['id' => 1])->one();
});
Информация: Некоторые СУБД (например, MySQL) поддерживают кэширование запросов любого механизма на стороне сервера БД. КЗ описано разделом выше. Оно имеет безусловное преимущество, поскольку, благодаря ему, можно указать гибкие зависимости кэша и это более эффективно.
Для очистки всего кэша, вы можете вызвать yii\caching\Cache::flush().
Также вы можете очистить кэш из консоли, вызвав yii cache/flush
.
yii cache
: отображает список доступных кэширующих компонентов приложенияyii cache/flush cache1 cache2
: очищает кэш в компонентах cache1
, cache2
(можно передать несколько названий
компонентов кэширования, разделяя их пробелом)yii cache/flush-all
: очищает кэш во всех кэширующих компонентах приложенияyii cache/flush-schema db
: очищает кеш схемы базы данных для данного компонента соединенияИнформация: Консольное приложение использует отдельный конфигурационный файл по умолчанию. Для получения должного результата, убедитесь, что в конфигурациях консольного и веб-приложения у вас одинаковые компоненты кэширования.
Кэширование запросов имеет три глобальных конфигурационных параметра через yii\db\Connection:
true
. Стоит отметить, что для использования кэширования вам может понадобиться компонент cache, как показано в queryCache;0
. Именно это значение выставляется yii\db\Connection::cache(), если не указать время явно;'cache'
. Кэширования запросов работает только в том случае, если используется компонент приложения кэш.Вы можете использовать yii\db\Connection::cache(), если у вас есть несколько SQL запросов, которые необходимо закэшировать:
$duration = 60; // кэширование результата на 60 секунд
$dependency = ...; // параметры зависимости
$result = $db->cache(function ($db) {
// ... выполнять SQL запросы здесь ...
return $result;
}, $duration, $dependency);
Любые SQL запросы в анонимной функции будут кэшироваться в течение указанного промежутка времени и с помощью заданной зависимости. Если результат запроса в кэше актуален, запрос будет пропущен, и вместо этого из кэша будет возвращен результат. Если вы не укажете параметр '$duration'
, то значение queryCacheDuration будет использоваться вместо него.
Иногда в пределах "cache()"
вы можете захотеть отключить кэширование запроса. В этом случае вы можете использовать yii\db\Connection::noCache().
$result = $db->cache(function ($db) {
// SQL запросы, которые используют кэширование
$db->noCache(function ($db) {
// SQL запросы, которые не используют кэширование
});
// ...
return $result;
});
Если вы просто хотите использовать кэширование для одного запроса, вы можете вызвать yii\db\Command::cache() при построении команды. Например:
// использовать кэширование запросов и установить срок действия кэша на 60 секунд
$customer = $db->createCommand('SELECT * FROM customer WHERE id=1')->cache(60)->queryOne();
Вы также можете использовать yii\db\Command::noCache() для отключения кэширования запросов для одной команды. Например:
$result = $db->cache(function ($db) {
// Используется кэширование SQL запросов
// не использовать кэширование запросов для этой команды
$customer = $db->createCommand('SELECT * FROM customer WHERE id=1')->noCache()->queryOne();
// ...
return $result;
});
Кэширование запросов не работает с результатами запросов, которые содержат обработчики ресурсов. Например, при использовании столбца типа BLOB
в некоторых СУБД, в качестве результата запроса будет возвращен указатель на ресурс для этого столбца данных.
Некоторые кэш хранилища имеют ограничение в размере данных. Например, Memcache ограничивает максимальный размер каждой записи до 1 Мб. Таким образом, если результат запроса превышает этот предел, данные не будут закэшированы.
Found a typo or you think this page needs improvement?
Edit it on github !
Signup or Login in order to comment.