Глава 4. Zend_Cache
Пред. |  | След.

## Глава 4. Zend_Cache

## 4.1. Введение

`Zend_Cache` предназначен для кэширования любых данных.

Управление кэшированием в Zend Framework производится через фронтэнды (интерфейсные части), записи кэша сохраняются через бэкэнды (адаптеры `File`, `Sqlite`, `Memcache` и др.), с использованием гибкой системы идентификаторов и тегов, благодаря которым можно потом легко удалять определенные типы записей (например: "удалить все записи кэша, помеченные данным тегом").

Ядро модуля (`Zend_Cache_Core`) является гибким, универсальным и конфигурируемым. Кроме этого, для особых нужд есть фронтэнды, расширяющие `Zend_Cache_Core`: `Output`, `File`, `Function` и `Class`.

Пример 4.1. Получение фронтэнда с помощью `Zend_Cache::factory()`

`Zend_Cache::factory()` инстанцирует нужные объекты и связывает их. В этом первом примере мы будем использовать фронтэнд `Core` с бэкэндом `File`.

    <?php
    require_once 'Zend/Cache.php';

    $frontendOptions = array(
       'lifeTime' => 7200, // время жизни кэша - 2 часа
       'automaticSerialization' => true
    );

    $backendOptions = array(
        'cacheDir' => './tmp/' // директория, в которой размещаются файлы кэша
    );

    // получение объекта Zend_Cache_Core
    $cache = Zend_Cache::factory('Core', 'File', $frontendOptions, $backendOptions);

    ?>

Теперь, имея фронтэнд, мы можем кэшировать любые типы данных, используя сериализацию. Например, мы можем кэшировать результат очень ресурсоемкого запроса к БД. После его добавления в кэш не нужно будет даже подключаться к базе данных: записи извлекаются из кэша и выполняется процедура, обратная сериализации.

    <?php

    // $cache определен в предыдущем примере

    // проверка, есть ли уже запись в кэше:
    if(!$result = $cache->load('myresult')) {

        // промах кэша
        // установка соединения с базой данных

        $db = Zend_Db::factory( [...] );

        $result = $db->fetchAll('SELECT * FROM huge_table');

        $cache->save($result, 'myresult');

    } else {

        // попадание в кэш
        echo "This one is from cache!\n\n";

    }

    print_r($result);

    ?>

Пример 4.2. Кэширование выходных данных с помощью фронтэнда `Zend_Cache`

Мы размечаем участки, внутри которых хотим поместить в кэш выходные данные, добавлением условной логики, окружая участок методами `start()` и `end()`. Этот пример похож на первый и является основной стратегией кэширования.

Внутри выводим данные как обычно — весь вывод будет добавлен в кэш, когда будет достигнут метод `end()`. При следующем запуске весь участок кода будет пропущен, вместо этого извлекаются данные из кэша (до тех пор, пока записи действительны).

    <?php

    $frontendOptions = array(
       'lifeTime' => 30,                  // время жизни кэша - половина минуты
       'automaticSerialization' => false  // уже установлено по умолчанию
    );

    $backendOptions = array('cacheDir' => './tmp/');

    $cache = Zend_Cache::factory('Output', 'File', $frontendOptions, $backendOptions);

    // передаем уникальный идентификатор методу start()
    if(!$cache->start('mypage')) {
        // производим вывод, как обычно:

        echo 'Hello world! ';
        echo 'This is cached ('.time().') ';

        $cache->end(); // выходные данные сохранены и отправлены броузеру
    }

    echo 'This is never cached ('.time().').';

    ?>

Обратите внимание, что мы выводим результат `time()` дважды: это демонстрация на примере динамических данных. Попробуйте запустить это и обновить страницу несколько раз. Вы заметите, что первое число не изменяется, в то время как второе меняется в зависимости от текущего времени. Это потому, что первое число было выведено в кэшируемой части и сохранено среди других выходных данных. После того, как пройдет полминуты (мы установили время жизни кэша равным 30 секундам) числа снова должны стать одинаковыми, потому что срок действия кэша истек, сразу после этого производится новое сохранение в кэш.

| Замечание
Когда используете `Zend_Cache`, уделяйте внимание идентификатору кэша (передается методам `save()` и `start()`). Он должен быть уникальным для каждого ресурса, который вы кэшируете, иначе не связанные записи кэша могут затирать друг друга, или, что еще хуже, отображаться вместо других.

Пред. |  | След.
3.2. Digest Authentication | Начало | 4.2. Теория кэширования