Кешування даних — це зберігання деякої змінної 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 максимальний розмір однієї одиниці даних дорівнює одному мегабайту. Тому, якщо розмір результату запита перевищить дане обмеження, то кешування не спрацює.
Found a typo or you think this page needs improvement?
Edit it on github !
Signup or Login in order to comment.