{{TOC}} {{DOCVER 5.3=c06d6a2352ed8c767633aab9c20f2bf7d880c967 28.01.2017 5:00:51, 5.2=6b0b057ae6de3c88cb29188459e38383c622ec23 8.12.2016 23:00:15, 5.1=cdc24ba7426c5b11eb4d050706bd78c3ea4913cc 19.06.2016 20:08:01, 5.0=5d10040a981deee82c0fde0e8e5d2ffc49eaaecb 8.02.2016 18:09:11}} == ((#configuration)) Настройка == Laravel предоставляет выразительный, универсальный API для различных систем кэширования. Настройки кэша находятся в файле %%(t)config/cache.php%%. Здесь вы можете указать драйвер, используемый по умолчанию в вашем приложении. Laravel изначально поддерживает многие популярные системы, такие как ((http://memcached.org/ Memcached)) и ((http://redis.io/ Redis)). Этот файл также содержит множество других настроек, которые в нём же документированы, поэтому обязательно ознакомьтесь с ними. По умолчанию, Laravel настроен для использования драйвера %%(t)file%%, который хранит сериализованные объекты кэша в файловой системе. Для больших приложений рекомендуется использование более надёжных драйверов, таких как Memcached или Redis. Вы можете настроить даже несколько конфигураций кэширования для одного драйвера. === Необходимые условия для драйверов === **База данных** Перед использованием драйвера **database** вам нужно создать таблицу для хранения элементов кэша. Ниже приведён пример объявления структуры %%(t)Schema%%: %% Schema::create('cache', function ($table) { $table->string('key')->unique(); $table->text('value'); $table->integer('expiration'); }); %% %%(DOCNEW 5.3=c06d6a2352ed8c767633aab9c20f2bf7d880c967 28.01.2017 5:00:51, 5.2=6b0b057ae6de3c88cb29188459e38383c622ec23 8.12.2016 23:00:15) .(alert) Также вы можете использовать Artisan-команду %%(sh)php artisan cache:table%% для генерации миграции с правильной схемой. %% **Система Memcached** Для использования системы кэширования Memcached необходим установленный ((http://pecl.php.net/package/memcached пакет Memcached PECL)). Вы можете перечислить все свои сервера Memcached в файле настроек %%(t)config/cache.php%%: %% 'memcached' => [ [ 'host' => '127.0.0.1', 'port' => 11211, 'weight' => 100 ], ], %% Вы также можете задать параметр %%(t)host%% для пути UNIX-сокета. В этом случае в параметр %%(t)port%% следует записать значение %%(t)0%%: %% 'memcached' => [ [ 'host' => '/var/run/memcached/memcached.sock', 'port' => 0, 'weight' => 100 ], ], %% **Система Redis** Перед тем, как использовать систему Redis необходимо установить пакет %%(t)predis/predis%% (~1.0) с помощью Composer. Загляните в раздел по ((/docs/v5/redis#configuration настройке Redis)) == Использование кэша == === Получение экземпляра кэша === ((/docs/v5/contracts Контракты)) %%(t)Illuminate\Contracts\Cache\Factory%% и %%(t)Illuminate\Contracts\Cache\Repository%% предоставляют доступ к службам кэша Laravel. Контракт %%(t)Factory%% предоставляет доступ ко всем драйверам кэша, определённым для вашего приложения. А контракт %%(t)Repository%% обычно является реализацией драйвера кэша по умолчанию для вашего приложения, который задан в файле настроек %%(t)cache%%. А также вы можете использовать фасад %%(t)Cache%%, который мы будем использовать в данной статье. Фасад %%(t)Cache%% обеспечивает удобный и лаконичный способ доступа к лежащим в его основе реализациям контрактов кэша Laravel: %% get('foo'); Cache::store('redis')->put('bar', 'baz', 10); %% === Получение элементов из кэша === Для получения элементов из кэша используется метод %%get()%% фасада %%(t)Cache%%. Если элемента в кэше не существует, будет возвращён %%null%%. При желании вы можете указать другое возвращаемое значение, передав его вторым аргументом метода %%get()%%: %% $value = Cache::get('key'); $value = Cache::get('key', 'default'); %% А также вы можете передать замыкание в качестве значения по умолчанию. Тогда, если элемента не существует, будет возвращён результат замыкания. С помощью замыкания вы можете настроить получение значений по умолчанию из базы данных или внешнего сервиса: %% $value = Cache::get('key', function () { return DB::table(...)->get(); }); %% **Проверка существования элемента** Для определения существования элемента в кэше используется метод %%has()%%. Он вернёт %%false%%, если значение равно %%null%%: %% if (Cache::has('key')) { // } %% **Увеличение/уменьшение значений** Для изменения числовых элементов кэша используются методы %%increment()%% и %%decrement()%%. Оба они могут принимать второй необязательный аргумент, определяющий значение, на которое нужно изменить значение элемента: %% Cache::increment('key'); Cache::increment('key', $amount); Cache::decrement('key'); Cache::decrement('key', $amount); %% **Получить или сохранить** Иногда необходимо получить элемент из кэша и при этом сохранить значение по умолчанию, если запрашиваемый элемент не существует. Например, когда необходимо получить всех пользователей из кэша, а если они не существуют, получить их из базы данных и добавить в кэш. Это можно сделать с помощью метода %%Cache::remember()%%: %% $value = Cache::remember('users', $minutes, function () { return DB::table('users')->get(); }); %% Если элемента нет в кэше, будет выполнено переданное в метод %%remember()%% замыкание, а его результат будет помещён в кэш. %%(DOCNEW 5.2=6b0b057ae6de3c88cb29188459e38383c622ec23 8.12.2016 23:00:15, 5.1=cdc24ba7426c5b11eb4d050706bd78c3ea4913cc 19.06.2016 20:08:01, 5.0=5d10040a981deee82c0fde0e8e5d2ffc49eaaecb 8.02.2016 18:09:11) Также можно комбинировать методы %%remember()%% и %%forever()%%: ~%% $value = Cache::rememberForever('users', function() { return DB::table('users')->get(); }); ~%% %% **Получить и удалить** При необходимости получить элемент и удалить его из кэша используется метод %%pull()%%. Как и метод %%get()%%, данный метод вернёт %%null%%, если элемента не существует: %% $value = Cache::pull('key'); %% === Сохранение элементов в кэш === Для помещения элементов в кэш используется метод %%put()%% фасада %%(t)Cache%%. При помещении элемента в кэш необходимо указать, сколько минут его необходимо хранить: %% Cache::put('key', 'value', $minutes); %% Вместо указания количества минут, можно передать экземпляр PHP-типа %%DateTime%%, для указания времени истечения срока хранения: %% $expiresAt = Carbon::now()->addMinutes(10); Cache::put('key', 'value', $expiresAt); %% **Сохранить, если такого нет** Метод %%add()%% просто добавит элемент в кэш, если его там ещё нет. Метод вернёт %%(t)true%%, если элемент действительно будет добавлен в кэш. Иначе - %%(t)false%%: %% Cache::add('key', 'value', $minutes); %% **Сохранить навсегда** Для бесконечного хранения элемента кэша используется метод %%forever()%%. Поскольку срок хранения таких элементов не истечёт никогда, они должны удаляться из кэша вручную с помощью метода %%forget()%%: %% Cache::forever('key', 'value'); %% .(alert) При использовании драйвера Memcached элементы, сохранённые "навсегда", могут быть удалены, когда размер кэша достигнет своего лимита. === Удаление элементов из кэша === Можно удалить элементы из кэша с помощью метода %%forget()%%: %% Cache::forget('key'); %% Вы можете очистить весь кэш методом %%flush()%%: %% Cache::flush(); %% .(alert) Очистка не поддерживает префикс кэша и удаляет из него все элементы. Учитывайте это при очистке кэша, которым пользуются другие приложения. %%(DOCNEW 5.3=c06d6a2352ed8c767633aab9c20f2bf7d880c967 28.01.2017 5:00:51) === Вспомогательная функция %%Cache()%% === Помимо использования фасада %%(t)Cache%% или ((//docs/v5/contracts контракта кэша)), вы также можете использовать глобальную функцию %%cache()%% для получения данных из кэша и помещения данных в него. При вызове функции %%cache()%% с одним строковым аргументом она вернёт значение данного ключа: ~%% $value = cache('key'); ~%% Если вы передадите в функцию массив пар ключ/значение и время хранения, она сохранит значения в кэше на указанное время: ~%% cache(['key' => 'value'], $minutes); cache(['key' => 'value'], Carbon::now()->addSeconds(10)); ~%% .(alert) При тестировании вызова глобальной функции %%cache()%% вы можете использовать метод %%Cache::shouldReceive()%%, как при ((//docs/v5/mocking тестировании фасада)). %% == Теги кэша == .(alert) Теги кэша не поддерживаются драйверами %%(t)file%% и %%(t)database%%. Кроме того, при использовании нескольких тегов для кэшей, хранящихся "вечно", лучшая производительность будет достигнута при использовании такого драйвера как %%(t)memcached%%, который автоматически зачищает устаревшие записи. === Сохранение элементов с тегами === Теги кэша позволяют отмечать связанные элементы в кэше, и затем сбрасывать все элементы, которые были отмеченны одним тегом. Вы можете обращаться к кэшу с тегами, передавая упорядоченный массив имён тегов. Например, давайте обратимся к кэшу с тегами и поместим в него значение методом %%put()%%: %% Cache::tags(['people', 'artists'])->put('John', $john, $minutes); Cache::tags(['people', 'authors'])->put('Anne', $anne, $minutes); %% === Обращение к элементам кэша с тегами === Для получения элемента с тегом передайте тот же упорядоченный список тегов в метод %%tags()%%, а затем вызовите метод %%get()%% с тем ключом, который необходимо получить: %% $john = Cache::tags(['people', 'artists'])->get('John'); $anne = Cache::tags(['people', 'authors'])->get('Anne'); %% === Удаление элементов кэша с тегами === Вы можете очистить все элементы с заданным тегом или списком тегов. Например, следующий код удалит все элементы, отмеченные либо тегом **people**, либо **authors**, либо и тем и другим. Поэтому и **Anne** и **John** будут удалены из кэша: %% Cache::tags(['people', 'authors'])->flush(); %% В отличие от предыдущего, следующий код удалит только те элементы, которые отмечены тегом **authors**, поэтому **Anne** будет удалён, а **John** - нет: %% Cache::tags('authors')->flush(); %% == Добавление своих драйверов кэша == === Написание драйвера === Чтобы создать свой драйвер кэша, нам надо сначала реализовать ((/docs/v5/contracts контракт)) %%(t)Illuminate\Contracts\Cache\Store%%. Итак, наша реализация кэша MongoDB будет выглядеть примерно так: %%(DOCNEW 5.3=c06d6a2352ed8c767633aab9c20f2bf7d880c967 28.01.2017 5:00:51) ~%% [ 'App\Listeners\LogCacheHit', ], 'Illuminate\Cache\Events\CacheMissed' => [ 'App\Listeners\LogCacheMissed', ], 'Illuminate\Cache\Events\KeyForgotten' => [ 'App\Listeners\LogKeyForgotten', ], 'Illuminate\Cache\Events\KeyWritten' => [ 'App\Listeners\LogKeyWritten', ], ]; ~%% %% %%(DOCNEW 5.1=f60f8b3697b3ffe381df4ddb7e2875ffce940643 1.04.2016 17:39:10, 5.0=5d10040a981deee82c0fde0e8e5d2ffc49eaaecb 8.02.2016 18:09:11) Для выполнения какого-либо кода при каждой операции с кэшем вы можете прослушивать ((/docs/v5/events события)), инициируемые кэшем. Обычно вам необходимо поместить эти слушатели событий в метод %%boot()%% вашего %%(t)EventServiceProvider%%: ~%% /** * Регистрация любых других событий для вашего приложения. * * @param \Illuminate\Contracts\Events\Dispatcher $events * @return void */ public function boot(DispatcherContract $events) { parent::boot($events); $events->listen('cache.hit', function ($key, $value) { // }); $events->listen('cache.missed', function ($key) { // }); $events->listen('cache.write', function ($key, $value, $minutes) { // }); $events->listen('cache.delete', function ($key) { // }); } ~%% %%