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

Фрагменты и база

В Yii полезно использовать кеширование не только SQL-запросов, но и HTML-фрагментов страницы. Очень удобно то, что можно обрамить кеширующим блоком вызов любого более-менее статичного виджета в представлении или лэйауте чтобы он не пересобирался каждый раз заново. Но при этом возникает необходимость в придумывании для каждого фрагмента уникального ключа, по которому он будет записан в кэше.

Автоматически закэшировать виджет «Следите за мной» под идентификатором «123456» на 3600 секунд можно так:

<?php
<?php if($this->beginCache(123456, array('duration'=>3600))) { ?>
    <?php $this->widget('application.widgets.FollowWidget');?>
<?php $this->endCache(); } ?>

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

В связи с этим приходилось постоянно следить за уникальностью ключей при копировании и перемещении по тексту кэширующих операторов. С ростом числа файлов это стало сильно отвлекать и, в конце концов, изрядно надоело. Чтобы при «аццком копипасте» не допускать всяких оплошностей придумалось простое решение. Просто инкапсулируем создание постоянного уникального ключа в сам оператор:

<?php
<?php if($this->beginCache(__FILE__.__LINE__, array('duration'=>3600))) { ?>
    Закешированный статичный фрагмент
<?php $this->endCache(); } ?>

И всё. Этот блок теперь можно спокойно копировать из вида в вид, не заботясь о случайных совпадениях идентификаторов. Значение выражения __FILE__.__LINE__ не повторится нигде. Это уже подойдёт для виджетов, не зависящих от адреса страницы.

Если же какой-либо виджет зависит от внешних факторов (например, виджет похожих записей зависит от ID текущего поста), то просто приписываем эти факторы к идентификатору:

<?php
<?php if($this->beginCache(__FILE__.__LINE__.'_'.$model->id, array('duration'=>30))) { ?>
    Закешированный фрагмент, зависящий от $model->id
<?php $this->endCache(); } ?>

Теперь для каждого поста будут показаны свои похожие записи.

Комментарии

 

Евгений

Гениально, спасибо.

Ответить

 

Bagration

С неймспейсами может и не прокатить

Ответить

 

Bagration

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

Лучше уж тогда хешировать полученную строку, например в md5()

Ответить

 

Дмитрий Елисеев

Yii сам хэширует переданный ключ в md5(), так что ограничений на длину ключа нет и полное имя файла с путём __FILE__ спокойно влезет.

Ответить

 

Стас

Дмитрий, залез к вам на сайт как в справочник! :) нужна была тема по кэшированию, точнее по memcache, никогда с этим чудом не работал, а теперь созрело.Но ничего не нашел. Может будет время на статейку по этой теме. Понимаю так же что yii2 уже во всю вылезает, но тем не менее на yii1 работ хватает. Спасибо.

Ответить

 

Андрей

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

Ответить

Оставить комментарий

Войти | Завести аккаунт | Войти через


(никто не увидит)





Можно использовать теги <p> <ul> <li> <b> <i> <a> <pre>