Кеш
Конфігурація
Laravel забезпечує виразний уніфікований API для різних кешуючих кеш-файлів. Конфігурація кешу знаходиться за адресоюconfig/cache.php
. У цьому файлі ви можете вказати, який драйвер кешу ви хочете використовувати за замовчуванням у всій програмі. Laravel підтримує такі популярні кешування, якMemcached,Редіс, іДинамоДБз коробки. Laravel також підтримує APC, Array, Database, File таnull
кеш драйвера.
Файл конфігурації кешу також містить різні інші параметри, які задокументовані у файлі, тому обов’язково прочитайте ці параметри. За замовчуванням Laravel налаштовано на використанняfile
кеш-драйвер, який зберігає серіалізовані кешовані об’єкти у файловій системі. Для великих програм рекомендується використовувати більш надійний драйвер, такий як Memcached або Redis. Ви навіть можете налаштувати кілька конфігурацій кешу для одного драйвера.
Передумови драйвера
База даних
При використанніdatabase
кеш-драйвер, вам потрібно буде налаштувати таблицю, щоб містити елементи кешу. Ви знайдете прикладSchema
декларація для таблиці нижче:
Schema::create('cache', function ($table) {
$table->string('key')->unique();
$table->text('value');
$table->integer('expiration');
});
Ви також можете використовуватиphp artisan cache:table
Команда Artisan для генерації міграції з відповідною схемою.
Memcached
Using the Memcached driver requires the Пакет Memcached PECLдля встановлення. Ви можете перерахувати всі свої сервери Memcached уconfig/cache.php
файл конфігурації:
'memcached' => [
[
'host' => '127.0.0.1',
'port' => 11211,
'weight' => 100
],
],
Ви також можете встановитиhost
опція до шляху сокета UNIX. Якщо ви зробите це,port
для параметра слід встановити значення0
:
'memcached' => [
[
'host' => '/var/run/memcached/memcached.sock',
'port' => 0,
'weight' => 100
],
],
Редіс
Перш ніж використовувати кеш Redis з Laravel, вам доведеться або встановити розширення PHpRedis PHP через PECL, або встановитиpredis/predis
пакет (~ 1.0) через Composer.
Щоб отримати додаткову інформацію про налаштування Redis, перегляньте йогоСторінка документації Laravel.
Використання кешу
Отримання екземпляра кешу
Illuminate\Contracts\Cache\Factory
іIlluminate\Contracts\Cache\Repository
контрактинадати доступ до кеш-послуг Laravel.Factory
Договір надає доступ до всіх драйверів кешу, визначених для вашої програми.Repository
Контракт, як правило, є реалізацією драйвера кешування за замовчуванням для Вашої програми, як вказано Вашимcache
файл конфігурації.
Однак ви також можете використовуватиCache
фасад, що і будемо використовувати в цій документації.Cache
Facadeзабезпечує зручний, стислий доступ до основних реалізацій контрактів кешування Laravel:
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\Cache;
class UserController extends Controller
{
/**
* Show a list of all users of the application.
*
* @return Response
*/
public function index()
{
$value = Cache::get('key');
//
}
}
Доступ до декількох магазинів кеш-пам’яті
ВикористанняCache
Фасад, ви можете отримати доступ до різних сховищ кешу черезstore
метод. Ключ переданий доstore
метод повинен відповідати одному з магазинів, перелічених уstores
конфігураційний масив у вашомуcache
файл конфігурації:
$value = Cache::store('file')->get('foo');
Cache::store('redis')->put('bar', 'baz', 600); // 10 Minutes
Отримання елементів із кешу
get
method on the Cache
Facadeвикористовується для отримання елементів з кешу. Якщо елемент не існує в кеші,null
буде повернено. Якщо ви хочете, ви можете передати другий аргументget
метод, що визначає значення за замовчуванням, яке потрібно повернути, якщо елемент не існує:
$value = Cache::get('key');
$value = Cache::get('key', 'default');
Ви можете навіть скластиClosure
як значення за замовчуванням. РезультатClosure
буде повернено, якщо вказаний елемент не існує в кеші. Передача закриття дозволяє відкласти отримання значень за замовчуванням з бази даних або іншої зовнішньої служби:
$value = Cache::get('key', function () {
return DB::table(...)->get();
});
Перевірка наявності товару
has
метод може бути використаний, щоб визначити, чи існує елемент у кеші. Цей метод повернетьсяfalse
якщо значення дорівнюєnull
:
if (Cache::has('key')) {
//
}
Збільшення / зменшення значень
increment
іdecrement
methods may be used to adjust the value of integer items in the cache. Both of these methods accept an optional second argument indicating the amount by which to increment or decrement the item's value:
Cache::increment('key');
Cache::increment('key', $amount);
Cache::decrement('key');
Cache::decrement('key', $amount);
Отримати та зберегти
Іноді вам може знадобитися отримати елемент із кешу, але також зберегти значення за замовчуванням, якщо запитуваний елемент не існує. Наприклад, можливо, ви захочете отримати всіх користувачів із кешу або, якщо вони не існують, отримати їх із бази даних та додати до кешу. Ви можете зробити це за допомогоюCache::remember
метод:
$value = Cache::remember('users', $seconds, function () {
return DB::table('users')->get();
});
Якщо елемент не існує в кеші, файлClosure
перейшов доremember
буде виконано, а його результат буде поміщено в кеш.
Ви можете використовуватиrememberForever
спосіб отримати елемент з кешу або зберегти його назавжди:
$value = Cache::rememberForever('users', function () {
return DB::table('users')->get();
});
Отримати та видалити
Якщо вам потрібно отримати елемент з кешу, а потім видалити елемент, ви можете використовуватиpull
метод. Подобаєтьсяget
метод,null
буде повернено, якщо елемент не існує в кеші:
$value = Cache::pull('key');
Зберігання Objects у кеші
Ви можете використовуватиput
метод наCache
Facadeдля зберігання Objects у кеші:
Cache::put('key', 'value', $seconds);
Якщо час зберігання не передано вput
метод, предмет буде зберігатися необмежений час:
Cache::put('key', 'value');
Замість того, щоб передавати кількість секунд як ціле число, ви також можете передати aDateTime
екземпляр, що представляє час закінчення кешованого елемента:
Cache::put('key', 'value', now()->addMinutes(10));
Зберігати, якщо немає
add
метод додасть елемент до кешу, лише якщо він ще не існує у сховищі кешу. Метод повернетьсяtrue
якщо елемент фактично додано до кешу. В іншому випадку метод повернетьсяfalse
:
Cache::add('key', 'value', $seconds);
Зберігання Objects назавжди
forever
метод може використовуватися для постійного зберігання елемента в кеші. Оскільки ці елементи не закінчуються, їх потрібно вручну видалити з кешу за допомогоюforget
метод:
Cache::forever('key', 'value');
Якщо ви використовуєте драйвер Memcached, елементи, які зберігаються "назавжди", можуть бути видалені, коли кеш досягне граничного розміру.
Видалення елементів із кешу
Ви можете видалити елементи з кешу за допомогоюforget
метод:
Cache::forget('key');
Ви також можете видалити елементи, надавши нульовий або від’ємний TTL:
Cache::put('key', 'value', 0);
Cache::put('key', 'value', -5);
Ви можете очистити весь кеш за допомогоюflush
метод:
Cache::flush();
Очищення кеш-пам’яті не поважає префікс кеш-пам’яті та видалить усі записи з кешу. Розгляньте це уважно, очищаючи кеш-пам’ять, яким користуються інші програми.
Помічник кешу
На додаток до використанняCache
Facadeабодоговір кешування, Ви також можете використовувати глобальнийcache
функція для отримання та збереження даних через кеш. Колиcache
Функція викликається одним аргументом рядка, вона поверне значення даного ключа:
$value = cache('key');
Якщо ви надаєте масив пар ключ / значення та час закінчення для функції, вона буде зберігати значення в кеші протягом зазначеної тривалості:
cache(['key' => 'value'], $seconds);
cache(['key' => 'value'], now()->addMinutes(10));
Колиcache
Функція викликається без будь-яких аргументів, вона повертає екземплярIlluminate\Contracts\Cache\Factory
реалізація, що дозволяє викликати інші методи кешування:
cache()->remember('users', $seconds, function () {
return DB::table('users')->get();
});
Під час тестування дзвінок у глобальнийcache
Ви можете використовуватиCache::shouldReceive
метод так само, як ніби тивипробування фасаду.
Теги кешу
Теги кешу не підтримуються під час використанняfile
,dynamodb
, абоdatabase
драйвери кешу. Крім того, при використанні декількох тегів з кешами, які зберігаються "назавжди", продуктивність буде найкращою з таким драйвером, якmemcached
, який автоматично видаляє застарілі записи.
Зберігання Tagged елементів кешу
Теги кеш-пам’яті дозволяють позначати пов’язані елементи в кеші, а потім очищати всі кешовані значення, яким було призначено даний тег. Ви можете отримати доступ до позначеного кешу, передавши впорядкований масив імен тегів. Наприклад, давайте отримаємо доступ до позначеного кешу таput
значення в кеші:
Cache::tags(['people', 'artists'])->put('John', $john, $seconds);
Cache::tags(['people', 'authors'])->put('Anne', $anne, $seconds);
Доступ до Tagged елементів кешу
Щоб отримати позначений елемент кешу, передайте той самий упорядкований список тегів доtags
а потім викличтеget
метод із ключем, який ви хочете отримати:
$john = Cache::tags(['people', 'artists'])->get('John');
$anne = Cache::tags(['people', 'authors'])->get('Anne');
Видалення Tagged елементів кешу
Ви можете очистити всі елементи, яким призначено тег або список тегів. Наприклад, це твердження видалить усі кеші, позначені будь-якимpeople
,authors
, або обидва. Отже, обидваAnne
іJohn
буде видалено з кешу:
Cache::tags(['people', 'authors'])->flush();
На відміну від цього, це твердження видалить лише кеші, позначені тегомauthors
, томуAnne
буде видалено, але ніJohn
:
Cache::tags('authors')->flush();
Atomic замки
Щоб використовувати цю функцію, ваша програма повинна використовуватиmemcached
,redis
,dynamodb
,database
,file
, абоarray
кеш-драйвер як драйвер кешу вашого додатка за замовчуванням. Крім того, усі сервери повинні взаємодіяти з одним і тим же сервером центрального кешу.
Передумови драйвера
База даних
При використанніdatabase
кеш-драйвер, вам потрібно буде налаштувати таблицю, щоб містити блокування кешу. Ви знайдете прикладSchema
декларація для таблиці нижче:
Schema::create('cache_locks', function ($table) {
$table->string('key')->primary();
$table->string('owner');
$table->integer('expiration');
});
Управління Locks
Atomic замки дозволяють маніпулювати розподіленими Locks, не турбуючись про умови перегонів. Наприклад,Кузня Laravelвикористовує Atomic блокування, щоб гарантувати, що на сервері одночасно виконується лише одне віддалене завдання. Ви можете створювати та керувати Locks за допомогоюCache::lock
метод:
use Illuminate\Support\Facades\Cache;
$lock = Cache::lock('foo', 10);
if ($lock->get()) {
// Lock acquired for 10 seconds...
$lock->release();
}
get
метод також приймає Закриття. Після виконання Закриття Laravel автоматично відпустить Lock:
Cache::lock('foo')->get(function () {
// Lock acquired indefinitely and automatically released...
});
Якщо Lock недоступний на момент запиту, ви можете доручити Laravel почекати вказану кількість секунд. Якщо Lock не вдається отримати протягом зазначеного терміну, aIlluminate\Contracts\Cache\LockTimeoutException
буде кинуто:
use Illuminate\Contracts\Cache\LockTimeoutException;
$lock = Cache::lock('foo', 10);
try {
$lock->block(5);
// Lock acquired after waiting maximum of 5 seconds...
} catch (LockTimeoutException $e) {
// Unable to acquire lock...
} finally {
optional($lock)->release();
}
Cache::lock('foo', 10)->block(5, function () {
// Lock acquired after waiting maximum of 5 seconds...
});
Управління Locks в різних процесах
Іноді, можливо, ви захочете отримати Lock в одному процесі та звільнити його в іншому процесі. Наприклад, ви можете отримати блокування під час веб-запиту і захочете звільнити блокування в кінці завдання, яке знаходиться в черзі, яке ініціюється цим запитом. У цьому сценарії ви повинні передати охоплюваний Lock "токен власника" до завдання в черзі, щоб завдання могло повторно створити блокування за допомогою даного маркера:
// Within Controller...
$podcast = Podcast::find($id);
$lock = Cache::lock('foo', 120);
if ($result = $lock->get()) {
ProcessPodcast::dispatch($podcast, $lock->owner());
}
// Within ProcessPodcast Job...
Cache::restoreLock('foo', $this->owner)->release();
Якщо ви хочете звільнити Lock, не поважаючи його поточного власника, ви можете використовуватиforceRelease
метод:
Cache::lock('foo')->forceRelease();
Додавання власних драйверів кешу
Написання драйвера
Щоб створити наш власний драйвер кешу, нам спочатку потрібно реалізуватиIlluminate\Contracts\Cache\Store
контракт. Отже, реалізація кешу MongoDB буде виглядати приблизно так:
<?php
namespace App\Extensions;
use Illuminate\Contracts\Cache\Store;
class MongoStore implements Store
{
public function get($key) {}
public function many(array $keys) {}
public function put($key, $value, $seconds) {}
public function putMany(array $values, $seconds) {}
public function increment($key, $value = 1) {}
public function decrement($key, $value = 1) {}
public function forever($key, $value) {}
public function forget($key) {}
public function flush() {}
public function getPrefix() {}
}
Нам просто потрібно реалізувати кожен із цих методів за допомогою з’єднання MongoDB. Для прикладу того, як реалізувати кожен із цих методів, погляньте наIlluminate\Cache\MemcachedStore
у вихідному коді фреймворку. Після завершення нашого впровадження ми зможемо закінчити власну реєстрацію драйверів.
Cache::extend('mongo', function ($app) {
return Cache::repository(new MongoStore);
});
Якщо вам цікаво, куди покласти власний код драйвера кеш-пам'яті, ви можете створити файлExtensions
простір імен у вашомуapp
каталог. Однак майте на увазі, що Laravel не має жорсткої структури додатків, і ви можете організувати свою заявку відповідно до своїх уподобань.
Реєстрація драйвера
Щоб зареєструвати власний драйвер кешу в Laravel, ми використаємоextend
метод наCache
фасад. Заклик доCache::extend
може бути зроблено вboot
метод за замовчуваннямApp\Providers\AppServiceProvider
що постачається зі свіжими програмами Laravel, або ви можете створити власного постачальника послуг для розміщення розширення - просто не забудьте зареєструвати постачальника вconfig/app.php
масив постачальника:
<?php
namespace App\Providers;
use App\Extensions\MongoStore;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\ServiceProvider;
class CacheServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
}
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Cache::extend('mongo', function ($app) {
return Cache::repository(new MongoStore);
});
}
}
Перший аргумент, переданий вextend
метод - це ім'я драйвера. Це відповідатиме вашомуdriver
варіант уconfig/cache.php
файл конфігурації. Другий аргумент - це Закриття, яке повинно повернути файлIlluminate\Cache\Repository
інстанції. Закриття буде прийнято$app
екземпляр, який є екземпляромслужбовий контейнер.
Після реєстрації вашого розширення оновітьconfig/cache.php
файли конфігураціїdriver
параметр до імені вашого розширення.
Події
Щоб виконати код на кожній операції кешування, ви можете прослухатиподіїспрацьовує кеш. Як правило, ви повинні розміщувати ці Listeners подій у вашомуEventServiceProvider
:
/**
* The event listener mappings for the application.
*
* @var array
*/
protected $listen = [
'Illuminate\Cache\Events\CacheHit' => [
'App\Listeners\LogCacheHit',
],
'Illuminate\Cache\Events\CacheMissed' => [
'App\Listeners\LogCacheMissed',
],
'Illuminate\Cache\Events\KeyForgotten' => [
'App\Listeners\LogKeyForgotten',
],
'Illuminate\Cache\Events\KeyWritten' => [
'App\Listeners\LogKeyWritten',
],
];