Кэширование

class Cake\Cache\Cache

Кэширование часто используется для сокращения времени, необходимого для создания или чтения из других источников. Кэширование часто используется для удишевления операции чтения из дорогих источников. В кеше вы можете хранить результаты ресурсоёмких запросов или удаленного доступа к веб-сервису, которые не часто изменяются. Повторное чтение сохраненного ресурса из кеша намного дешевле чем повторный запрос к удаленному ресурсу.

Кэширование в CakePHP в первую очередь облегчается классом Cache. Этот класс предоставляет набор статических методов, которые предоставляют единый API для работы со всеми типами реализаций кэширования. CakePHP поставляется с несколькими встроенными механизмами кэширования и обеспечивает удобную систему для реализации ваших собственных систем кэширования.

Встроенные механизмы кеширования:

  • FileCache (Файловый кеш) - это простой кэш, который использует локальные файлы. Он является самым медленным механизмом кэширования и не предоставляет функций для атомарных операций. Однако, поскольку дисковое хранилище часто довольно дешёвое, хранение больших объектов или элементов, которые нередко записываются в файлы, хорошо работает.
  • ApcCache - пользовательский кеш APC - использует расширение PHP APCu. Это расширение использует общую память на веб-сервере для хранения объектов. Это делает его очень быстрым и способным обеспечивать атомарные функции чтения/записи.
  • Wincache - использует расширение Wincache. Wincache похож на APC по функциям и производительности, но оптимизирован для Windows и IIS.
  • XcacheEngine - Xcache - является расширением PHP, которое предоставляет функции аналогичные APC.
  • MemcachedEngine - использует расширение - Memcached.
  • RedisEngine (Redis) - использует расширение - phpredis. Redis обеспечивает быструю и постоянную систему кэширования, похожую на Memcached и также обеспечивает атомарные операции.

Независимо от используемого вами CacheEngine, ваше приложение взаимодействует с Cake\Cache\Cache согласованным образом. Вы можете менять ваш CacheEngine, по мере того, как растёт ваше приложение.

Настройка класса кэша

static Cake\Cache\Cache::config($key, $config = null)

Настройка класса Cache может выполняться в любом месте, но в целом вы захотите настроить кеш во время начальной загрузки. Файл config/app.php сделан именно для таких нужд. Вы можете настроить столько кешей, сколько вам нужно, и использовать любую смесь движков кеша. CakePHP, внутри себя, использует две конфигурации кэша. _cake_core_ - используется для хранения файла карты и проанализированных результатов в файле Internationalization & Localization. _cake_model_ - используется для хранения описаний схем для моделей ваших приложений. Если вы используете APC или Memcached, вы должны установить уникальные ключи для основных кешей. Это предотвратит перезапись данных кеширования нескольких приложений друг-другом.

Использование нескольких конфигураций, также позволяет вам постепенно изменять хранилище как вам это нужно. Например, в вашем config/app.php вы можете указать следующее:

// ...
'Cache' => [
    'short' => [
        'className' => 'File',
        'duration' => '+1 hours',
        'path' => CACHE,
        'prefix' => 'cake_short_'
    ],
    // Использование пространства имён в качестве имени
    'long' => [
        'className' => 'Cake\Cache\Engine\FileEngine',
        'duration' => '+1 week',
        'probability' => 100,
        'path' => CACHE . 'long' . DS,
    ]
]
// ...

Параметры конфигурации также могут предоставляться как строка DSN. Это полезно при работе с переменными окружения или провайдерами PaaS:

Cache::config('short', [
    'url' => 'memcached://user:password@cache-host/?timeout=3600&prefix=myapp_',
]);

При использовании строки DSN вы можете определить любые дополнительные параметры/опции как аргументы строки запроса.

Вы также можете настроить механизмы кэширования, во время выполнения:

// Использование короткого имени
Cache::config('short', [
    'className' => 'File',
    'duration' => '+1 hours',
    'path' => CACHE,
    'prefix' => 'cake_short_'
]);

// Использование пространства имён в качестве имени, т.е. использование длинного имени
Cache::config('long', [
    'className' => 'Cake\Cache\Engine\FileEngine',
    'duration' => '+1 week',
    'probability' => 100,
    'path' => CACHE . 'long' . DS,
]);

// Использование построенного объекта.
$object = new FileEngine($config);
Cache::config('other', $object);

Название этих конфигураций „short“ или „long“ используется в $onfig как параметр для метода записи Cake\Cache\Cache::write() и чтения Cake\Cache\Cache::read(). При настройке CacheEngine вы можете обратится к имени класса, используя следующие варианты синтаксисов:

  • Короткое имя класса без „Engine“ или пространства имен. Это будет означать, что вы хотите использовать движок кэша Cake\Cache\Engine или App\Cache\Engine.
  • Использование plugin syntax, который позволяет загружать движки из определенного плагина.
  • Использование полного именини класса. Это позволяет использовать классы, расположенные за пределами обычного местоположения.
  • Использование объекта, который расширяет класс CacheEngine.

Примечание

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

Настройка откатов кэша

В случае, если движок недоступен, например, FileEngine пытается сделать запись в недоступную для записи папку, или RedisEngine, не может подключиться к Redis, движок NullEngine вернётся к noop („No OPeration“) и вызовет логическую ошибки. Это не позволит приложению отбросить неперехваченное исключение из-за кэша.

Вы можете настроить конфигурации кэша, чтобы, в таких случаях, вернуться к указанной конфигурации, используя ключ fallback:

Cache::config('redis', [
    'className' => 'Redis',
    'duration' => '+1 hours',
    'prefix' => 'cake_redis_',
    'host' => '127.0.0.1',
    'port' => 6379,
    'fallback' => 'default',
]);

Если сервер Redis неожиданно вышел из строя, то конфигурация записи в кеше redis вернётся к конфигурации default. Если запись в конфигурацию кеша default также не выполнится в этом сценарии, двигатель снова вернётся к NullEngine и предотвратит применение отбрасыния неперехваченного исключения.

Добавлено в версии 3.5.0: Добавлены резервные копии кэша.

Удаление сконфигурированных кеш-двигателей

static Cake\Cache\Cache::drop($key)

После создания конфигурации вы не сможете её изменить. Вместо этого вам следует удалить конфигурацию и воссоздать её, используя удаление - Cake\Cache\Cache::drop() и новое конфигурирование - Cake\Cache\Cache::config(). Удаление механизма кеша удалит config и уничтожит адаптер, если он был сконструирован.

Запись в кэш

static Cake\Cache\Cache::write($key, $value, $config = 'default')

Cache::write() будет писать $value для кэша. Вы можете прочесть или удалить это значение позже, обратившись к нему с помощью $key. Вы можете указать дополнительную конфигурацию для хранения кэша. Если нет $config, используется значение по умолчанию. Cache::write() может хранить любой тип объекта и идеально подходит для хранения истории результатов поиска моделей:

if (($posts = Cache::read('posts')) === false) {
    $posts = $someService->getAllPosts();
    Cache::write('posts', $posts);
}

Методы Cache::write() и Cache::read() могут использоваться для уменьшения числа запросов, сделанных в базу данных.

Примечание

Если вы планируете кэшировать результат запросов, созданных с помощью CakePHP ORM, лучше использовать встроенные возможности кеша объекта Query как описано в разделе Caching Loaded Results

Написание нескольких ключей одновременно

static Cake\Cache\Cache::writeMany($data, $config = 'default')

Возможно, вам понадобится написать несколько ключей кеша сразу. writeMany() позволяет CakePHP использовать более эффективный API хранения данных, там где он доступен, нежели write(). Например, использование writeMany() может сохранять несколько сетевых подключений при использовании Memcached:

$result = Cache::writeMany([
    'article-' . $slug => $article,
    'article-' . $slug . '-comments' => $comments
]);

// Будет содержать $result
['article-first-post' => true, 'article-first-post-comments' => true]

Чтение через кеширование

static Cake\Cache\Cache::remember($key, $callable, $config = 'default')

Кэш облегчает чтение кеширования. Если именованный ключ кеша существует, он будет возвращен. Если ключ не существует, будет вызван callable и результаты, хранящиеся в кеше, по предоставленному ключу.

Например, вы хотите часто кэшировать результаты вызова удаленной службы. Вы можете использовать remember(), чтобы сделать это простой задачей:

class IssueService
{
    public function allIssues($repo)
    {
        return Cache::remember($repo . '-issues', function () use ($repo) {
            return $this->fetchAll($repo);
        });
    }
}

Чтение из кеша

static Cake\Cache\Cache::read($key, $config = 'default')

Cache::read() используется для чтения закэшированного значения, хранящегося в $key из $config. Если $config равно null, то будет использоваться значение по умолчанию. Cache::read() вернёт кешированное значение если это действительный кеш или false, если срок жизни кеша истёк или запрошенный файл кэша не существует. Содержимое кеша может быть false, поэтому убедитесь, что вы используете строгие операторы сравнения: === или !==.

Например:

$cloud = Cache::read('cloud');

if ($cloud !== false) {
    return $cloud;
}

// Создание данных облака
// ...

// Сохраним данные в кеше
Cache::write('cloud', $cloud);
return $cloud;

Одновременное чтение нескольких ключей

static Cake\Cache\Cache::readMany($keys, $config = 'default')

После того, как вы сразу записали несколько ключей, вы, вероятно, захотите их прочитать. Хотя вы и можете использовать несколько вызовов read(), но всётаки readMany() позволяет CakePHP использовать более эффективные API хранения, если они доступны. Например, используя readMany() мы можем сохранить несколько сетевых подключений, при использовании Memcached:

$result = Cache::readMany([
    'article-' . $slug,
    'article-' . $slug . '-comments'
]);
// Будет содержать $result
['article-first-post' => '...', 'article-first-post-comments' => '...']

Удаление из кэша

static Cake\Cache\Cache::delete($key, $config = 'default')

Cache::delete() позволит вам полностью удалить закешированный объект из истории:

// Удаление ключа
Cache::delete('my_key');

Одновременное удаление нескольких ключей

static Cake\Cache\Cache::deleteMany($keys, $config = 'default')

После того, как вы написали сразу несколько ключей, вы можете удалить их. В то время как вы можете использовать несколько вызовов delete(), deleteMany() - позволяет CakePHP использовать более эффективный API хранения данных, если он доступен. Например, используем deleteMany() для удаления некольких сохранённых сетевых подключений, при использовании Memcached:

$result = Cache::deleteMany([
    'article-' . $slug,
    'article-' . $slug . '-comments'
]);
// Будет содержать $result
['article-first-post' => true, 'article-first-post-comments' => true]

Очистка закэшированных данных

static Cake\Cache\Cache::clear($check, $config = 'default')

Уничтожьте все закэшированные значения для конфигурации кэша. В таких двигателях, как Apc, Memcached и Wincache, префикс конфигурации кеша используется для удаления кэш-записи. Убедитесь, что разные конфигурации кеша отличаются префиксами:

// Очищаем только истёкшие ключи
Cache::clear(true);

// Очищаем все ключи
Cache::clear(false);
static Cake\Cache\Cache::gc($config)

Сборщик мусора собирает мусорные фалы кеша, основываясь на конфигурации кэша. Это в первую очередь используется FileEngine. Он должен быть реализован любым движком Cache, который требует ручного „выселения“ кэшированных данных.

Примечание

Поскольку APC и Wincache используют изолированные кеши для веб-сервера и CLI, они должны быть очищены отдельно (CLI не может почистить веб-сервер и наоборот).

Использование кеша для хранения счетчиков

static Cake\Cache\Cache::increment($key, $offset = 1, $config = 'default')
static Cake\Cache\Cache::decrement($key, $offset = 1, $config = 'default')

Счетчики в вашем приложении являются хорошими кандидатами для хранения в кеше. Так, например, может быть сохранен в кеше простой обратный отсчёт для оставшихся „слотов“ в конкурсе. Класс Cache предоставляет атомарные действия для увеличения/уменьшения(инкремента/дикремента) счетчика ценностей, в простой форме. Атомарные операции важны для этих значений, поскольку они снижают риск конкуренции и не позволят двум пользователям одновременно опустить значение на единицу, что могло бы привести к неправильному результату.

После установки целочисленного значения вы можете манипулировать ими с помощью методов increment() и decrement():

Cache::write('initial_count', 10);

// Later on
Cache::decrement('initial_count');

// Or
Cache::increment('initial_count');

Примечание

Инкремент и дикремент не работают с FileEngine. Вы должны использовать APC, Wincache, Redis или Memcached.

Использование кеша для хранения общих результатов запроса

Вы можете значительно повысить производительность своего приложения, добавив в кеш результаты которые редко меняются или являются ресурсоёмкими для чтения(получения). Прекрасным примером этого являются результаты Cake\ORM\Table::find(). Объект Query позволяет кэшировать результаты с использованием метода cache(). Чтобы получить больше информации см. раздел Caching Loaded Results.

Использование групп

Иногда, вам нужно отметить несколько записей кэша, принадлежащих определенной группе или пространству имен. Это требование является общим для массы недействительных ключей всякий раз, когда некоторые изменения информации разделяются между всеми элементами в одной и той же группе. Это возможно, и для этого нужно объявить такие группы при конфигурации кеша:

Cache::config('site_home', [
    'className' => 'Redis',
    'duration' => '+999 days',
    'groups' => ['comment', 'article']
]);
Cake\Cache\Cache::clearGroup($group, $config = 'default')

Предположим, вы хотите сохранить HTML-код, сгенерированный для вашей домашней страницы в кеше, но также хотите автоматически обнулять этот кеш каждый раз, когда в вашу базу данных добавляется новый комментарий или пост. Добавляя группы comment и article, мы эффективно отмечаем любой ключ, сохраненный в этой конфигурации кэша, с названиями обеих групп.

Например, всякий раз, когда добавляется новое сообщение, мы можем сказать движку Cache, чтобы он удалил все записи, связанные с группой article:

// src/Model/Table/ArticlesTable.php
public function afterSave($event, $entity, $options = [])
{
    if ($entity->isNew()) {
        Cache::clearGroup('article', 'site_home');
    }
}
static Cake\Cache\Cache::groupConfigs($group = null)

groupConfigs() можно использовать для получения сопоставления между группой и её конфигурацией:

// src/Model/Table/ArticlesTable.php

// Вариант предыдущего примера, который очищает все конфигурации кэша из той же группы
public function afterSave($event, $entity, $options = [])
{
    if ($entity->isNew()) {
        $configs = Cache::groupConfigs('article');
        foreach ($configs['article'] as $config) {
            Cache::clearGroup('article', $config);
        }
    }
}

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

Глобальное включение или отключение кеша

static Cake\Cache\Cache::disable

Если возникла необходимость отключить все операции чтения и записи кэша, например когда вы пытаетеь найти кеш с истёкшим сроком действия, вы можете сделать это, используя методы enable() и disable():

// Отключаем все операции чтения кеша и записи в кэш
Cache::disable();

После отключения, все попытки чтения и записи в кеш будут возвращать null.

static Cake\Cache\Cache::enable

После отключения вы можете использовать enable() для повторного включения кеширования:

// Снова включаем все операции чтения кеша и записи в кэш
Cache::enable();
static Cake\Cache\Cache::enabled

Чтобы проверить состояние кеширования (включено оно или нет), вы можете использовать enabled().

Создание механизма хранения для кеша

Вы можете предоставить настраиваемые Cache адаптеры в App\Cache\Engine как плагины, с использованием $plugin\Cache\Engine. Механизмы кэширования src/plugin могут также переопределять основные двигатели. Кэширующие адаптеры должны находится в каталоге кеша. Если у вас есть механизм кэширования с именем MyCustomCacheEngine он должен быть помещен либо в src/Cache/Engine/MyCustomCacheEngine.php как app/libs, либо в plugins/MyPlugin/src/Cache/Engine/MyCustomCacheEngine.php - как частный плагин.

Конфигурации кэша из плагинов должны использовать синтаксис плагина с точкой:

Cache::config('custom', [
    'className' => 'MyPlugin.MyCustomCache',
    // ...
]);

Механизмы пользовательского кэша должны наследоваться от Cake\Cache\CacheEngine, который определяет ряд абстрактных методов, а также предоставляет несколько методов инициализации.

Необходимым API для CacheEngine является:

class Cake\Cache\CacheEngine

Базовый класс движка, использующего кеш.

Cake\Cache\CacheEngine::write($key, $value, $config = 'default')
Результат:boolean for success.

Записывает значение для ключа в кеш. Необязательный строковый параметр $config указывает имя конфигурации для записи.

Cake\Cache\CacheEngine::read($key)
Результат:The cached value or false for failure.

Читает из кеша. Вернёт false если запись в кеше устарела или не существует.

Cake\Cache\CacheEngine::delete($key)
Результат:Boolean true on success.

Удаляет ключ из кеша. Вернёт false если запись в кеше устарела или не может быть удалена.

Cake\Cache\CacheEngine::clear($check)
Результат:Boolean true on success.
Удаляет все ключи из кеша. Если $check установлено в true, то вы должны
подтвердите, что каждое значение действительно истекло.
Cake\Cache\CacheEngine::clearGroup($group)
Результат:Boolean true on success.

Удаляет все ключи из кеша, относящиеся к одной группе.

Cake\Cache\CacheEngine::decrement($key, $offset = 1)
Результат:Boolean true on success.

Уменьшает числовое значение ключа и возвращает уменьшенное значение.

Cake\Cache\CacheEngine::increment($key, $offset = 1)
Результат:Boolean true on success.

Увеличивает числовое значение ключа и возвращает увеличинное значение.

Cake\Cache\CacheEngine::gc()

Не требуется, но используется для очистки, истёкших ресурсов. FileEngine использует этот метод для удаления файлов, содержащих контент с истёкшим временем.