Автоматический уникальный идентификатор для кеша
В Yii полезно использовать кеширование не только SQL-запросов, но и HTML-фрагментов страницы. Очень удобно то, что можно обрамить кеширующим блоком вызов любого более-менее статичного виджета в представлении или лэйауте чтобы он не пересобирался каждый раз заново. Но при этом возникает необходимость в придумывании для каждого фрагмента уникального ключа, по которому он будет записан в кэше.
Автоматически закэшировать виджет «Следите за мной» под идентификатором «123456» на 3600 секунд можно так:
<?php if($this->beginCache(123456, array('duration'=>3600))) { $this->widget('application.widgets.FollowWidget'); $this->endCache(); }
Я часто использую виджеты и шаблоны, поэтому в проектах порой приходится иметь дело с десятками представлений, лэйаутов и их частей (например, целый набор различных сайдбаров для разных разделов сайта).
В связи с этим приходилось постоянно следить за уникальностью ключей при копировании и перемещении по тексту кэширующих операторов. С ростом числа файлов это стало сильно отвлекать и, в конце концов, изрядно надоело. Чтобы при «аццком копипасте» не допускать всяких оплошностей придумалось простое решение. Просто инкапсулируем создание постоянного уникального ключа в сам оператор:
<?php if($this->beginCache(__FILE__.__LINE__, array('duration'=>3600))) { Закешированный статичный фрагмент $this->endCache(); }
И всё. Этот блок теперь можно спокойно копировать из вида в вид, не заботясь о случайных совпадениях идентификаторов. Значение выражения __FILE__.__LINE__
не повторится нигде. Это уже подойдёт для виджетов, не зависящих от адреса страницы.
Если же какой-либо виджет зависит от внешних факторов (например, виджет похожих записей зависит от ID текущего поста), то просто приписываем эти факторы к идентификатору:
<?php if($this->beginCache(__FILE__.__LINE__.'_'.$model->id, array('duration'=>30))) { Закешированный фрагмент, зависящий от $model->id $this->endCache(); }
Теперь для каждого поста будут показаны свои похожие записи.
Гениально, спасибо.
С неймспейсами может и не прокатить
Хотя нет, прокатит. Вот только может не поместиться в длину ключа, например в мемкеше.
Лучше уж тогда хешировать полученную строку, например в md5()
Yii сам хэширует переданный ключ в md5(), так что ограничений на длину ключа нет и полное имя файла с путём __FILE__ спокойно влезет.
Дмитрий, залез к вам на сайт как в справочник! :) нужна была тема по кэшированию, точнее по memcache, никогда с этим чудом не работал, а теперь созрело.Но ничего не нашел. Может будет время на статейку по этой теме. Понимаю так же что yii2 уже во всю вылезает, но тем не менее на yii1 работ хватает. Спасибо.
Стоить заметить, что если виджет производит регистрацию ассетов, то его кешировать нельзя, потому что тогда не будут подключены необходимые для работы виджета css и js файлы.