Кэширование данных — это хранение некоторой переменной PHP в кэше и получение её оттуда. Для этой цели базовый класс CCache компонента кэша имеет два наиболее используемых метода: set() и get().
Для кэширования переменной $value мы выбираем уникальный идентификатор (ID)
и вызываем метод set() для её сохранения в кэше:
Yii::app()->cache->set($id, $value);
Данные будут оставаться в кэше до тех пор, пока не будут удалены из-за некоторых условий функционирования кэша (например, места для кэширования не осталось, тогда более старые данные удаляются). Для изменения такого поведения мы можем установить значения срока действия кэша при вызове метода set(). Тогда данные будут удалены из кэша после определенного периода времени:
// храним значение переменной в кэше не более 30 секунд Yii::app()->cache->set($id, $value, 30);
Позже, когда нам понадобится доступ к этой переменной (в этом же или другом запросе), мы вызываем метод get() с идентификатором переменной. Если возвращенное значение — false, то переменная не доступна в кэше и мы должны регенерировать ее (обновить в кэше).
$value=Yii::app()->cache->get($id); if($value===false) { // обновляем $value, т.к. переменная не найдена в кэше, // и сохраняем в кэш для дальнейшего использования: // Yii::app()->cache->set($id,$value); }
При выборе идентификатора для кэшируемой переменной, учитывайте, что он должен быть уникальным для каждой переменной из тех, что могут быть кэшированы в приложении. НЕ требуется, чтобы идентификатор был уникальным между разными приложениями, потому что компонент кэша достаточно умен для различения идентификаторов разных приложений.
Некоторые кэш-хранилища, такие как MemCache, APC, поддерживают загрузку нескольких кэшированных значений в пакетном режиме, которая может уменьшить накладные расходы на получение данных, сохраненных в кэше. Метод mget() позволяет использовать эту особенность. В случае, когда кэш-хранилище не поддерживает эту функцию, mget() будет по-прежнему имитировать ее.
Для удаления кэшированного значения из кэша надо вызвать метод delete(), а для очистки всего кэша — вызвать метод flush(). Надо быть осторожным при вызове метода flush(), т.к. он также удаляет кэшированные данные других приложений.
Подсказка: класс CCache реализует
ArrayAccess, поэтому компонент кэша может использоваться как массив. Ниже приведены примеры:$cache=Yii::app()->cache; $cache['var1']=$value1; // эквивалентно $cache->set('var1',$value1); $value2=$cache['var2']; // эквивалентно $value2=$cache->get('var2');
Помимо установки срока действия, кэшируемые данные также могут стать недействительными в соответствии с некоторыми изменениями зависимости (dependency). Например, если мы кэшируем содержимое некоторого файла, и файл изменился, мы должны принять кэшированную копию как недействительную и считать свежее содержимое из файла, а не из кэша.
Мы представляем зависимость как экземпляр класса CCacheDependency или классов, его наследующих. Мы передаем экземпляр зависимости вместе с кэшируемыми данными, когда вызываем метод set().
// значение действительно не более 30 секунд // также, значение может стать недействительным раньше, если зависимый файл изменен Yii::app()->cache->set($id, $value, 30, new CFileCacheDependency('FileName'));
Теперь, если мы попытаемся получить значение $value из кэша, вызвав метод
get(), зависимость будет проверена и, если она изменилась, мы
получим значение false, показывающее, что данные требуют обновления.
Ниже приведен список доступных зависимостей кэша:
CFileCacheDependency: зависимость меняется, если время модификации файла изменено;
CDirectoryCacheDependency: зависимость меняется, если любой файл в каталоге или в подкаталогах изменен;
CDbCacheDependency: зависимость меняется, если результат запроса некоторого определенного SQL выражения изменен;
CGlobalStateCacheDependency: зависимость меняется, если значение определенного глобального состояния изменено. Глобальное состояние — это переменная, являющаяся постоянной в многократных запросах и сессиях приложения. Устанавливается методом CApplication::setGlobalState();
CChainedCacheDependency: зависимость меняется, если любая зависимость цепочки изменена;
CExpressionDependency: зависимость меняется, если результат определенного выражения PHP изменен.
В версию 1.1.7 Yii добавлена поддержка кэширования запросов. Построенное на кэшировании данных, кэширование запросов хранит результат запроса к базе данных в кэше и, тем самым, экономит время, расходуемое на одни и те же запросы.
Информация: Некоторые СУБД, такие как MySQL, поддерживают кэширование на стороне сервера базы данных. Поддержка кэша в Yii более гибкая и потенциально более эффективная.
Для того, чтобы включить кэширование запросов, убедитесь, что
в CDbConnection::queryCacheID находится ID подключенного компонента,
реализующего кэширование. По умолчанию это компонент cache.
Для того, чтобы использовать кэширования запросов необходимо вызвать метод CDbConnection::cache().
Пример:
$sql = 'SELECT * FROM tbl_post LIMIT 20'; $dependency = new CDbCacheDependency('SELECT MAX(update_time) FROM tbl_post'); $rows = Yii::app()->db->cache(1000, $dependency)->createCommand($sql)->queryAll();
При выполнении приведённого кода, Yii сначала проверит, есть ли в кэше актуальный результат, соответствующий SQL-запросу, который мы собираемся выполнить. При этом проверяется:
update_time то же, что
было при сохранении результата запроса в кэш).Если все три условия выполняются, то результат берётся из кэша. Иначе выполняется SQL запрос, его результат записывается в кэш и возвращается.
Кэширования запросов также можно использовать с Active Record. Для этого мы используем метод CActiveRecord::cache():
$dependency = new CDbCacheDependency('SELECT MAX(update_time) FROM tbl_post'); $posts = Post::model()->cache(1000, $dependency)->findAll(); // реляционный запрос $posts = Post::model()->cache(1000, $dependency)->with('author')->findAll();
Метод cache() является короткой записью вызова CDbConnection::cache().
При выполнении SQL запроса, сгенерированного ActiveRecord, Yii попытается
использовать кэширования также, как это было описано в предыдущем подразделе.
По умолчанию, каждый раз, когда мы вызываем метод cache() (как CDbConnection,
так и CActiveRecord), он кеширует следующий за его вызовом запрос. Все остальные
запросы НЕ кешируются пока мы не вызовем cache() ещё раз. К примеру:
$sql = 'SELECT * FROM tbl_post LIMIT 20'; $dependency = new CDbCacheDependency('SELECT MAX(update_time) FROM tbl_post'); $rows = Yii::app()->db->cache(1000, $dependency)->createCommand($sql)->queryAll(); // кэширование запроса НЕ используется $rows = Yii::app()->db->createCommand($sql)->queryAll();
Передавая методу cache() дополнительный параметр $queryCount, мы можем
закэшировать несколько выполняющихся подряд запросов. В следующем примере мы кэшируем
два запроса:
// ... $rows = Yii::app()->db->cache(1000, $dependency, 2)->createCommand($sql)->queryAll(); // будет использоваться кэширование запросов $rows = Yii::app()->db->createCommand($sql)->queryAll();
Как известно, при выполнении реляционного AR-запроса, могут использоваться
несколько SQL запросов (это можно узнать,
проверив журнал сообщений). К примеру, если
связь между Post и Comment типа HAS_MANY, то код, приведённый ниже,
выполнит два запроса:
$posts = Post::model()->with('comments')->findAll(array( 'limit'=>20, ));
Если использовать кэширование запросов, как показано ниже, закэширован будет только первый запрос к БД:
$posts = Post::model()->cache(1000, $dependency)->with('comments')->findAll(array( 'limit'=>20, ));
Для того, чтобы в кэш попали оба запроса, необходимо передать дополнительный параметр, задающий количество кэшируемых запросов:
$posts = Post::model()->cache(1000, $dependency, 2)->with('comments')->findAll(array( 'limit'=>20, ));
Кэширование запросов не работает с результатами, содержащими ссылки на ресурс.
К примеру, она возвращается в некоторых СУБД при использовании типа BLOB.
В некоторых хранилищах кэша есть ограничение на размер хранимых данных. К примеру, в memcache максимальный размер одной единицы данных равен одному мегабайту. Поэтому, если размер результата запроса превысит данное ограничение, то кэширование не сработает.
Be the first person to leave a comment
Please login to leave your comment.