# Введение

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

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

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

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

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

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

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

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

Фронтэнды и бэкэнды, содержащие несколько слов в названии

Некоторые фронтэнды и бэкэнды имеют имена, состоящие из нескольких слов, например, 'ZendPlatform'. Когда задаете их через фабрику, разделяйте слова с помощью разделителей, таких, как пробел (' '), тире ('-'), или точка ('.').

Кэширование результатов запросов к базе данных

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

    // $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);

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

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

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

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

    $backendOptions = array('cache_dir' => './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()). Он должен быть уникальным для каждого кэшируемого ресурса, иначе не связанные записи кэша могут затирать друг друга, или, что еще хуже, отображаться вместо других.