مشخصات مقاله
-
1969
-
0.0
-
6500
-
0
-
0
آموزش سرویس Cache در لاراول
سرویس Cache (ذخیره سازی موقت اطلاعات) در لاراول
- تنظیمات Cache
-
استفاده از Cache
- بازیابی یک نمونه Cache
- بازیابی آیتم از Cache
- ذخیره سازی آیتم در Cache
- حذف آیتم از Cache
-
Cache tag ها (تخصیص یک تگ به آیتم های ذخیره شده در کش)
- ذخیره سازی آیتم های تگ دار در cache
- دسترسی به آیتم های تگ دار در cache
- نحوه ی اضافه کردن cache driver های سفارشی
- رخدادها
تنظیمات Cache
Laravel یک API (رابط برنامه سازی کاربردی) متحدالشکل برای تمامی سیستم های ذخیره سازی موقت اطلاعات (caching) ارائه می کند. برای تنظیم سرویس cache می بایست به فایل کانفیگ config/cache.php مراجعه نمایید. در این فایل می توانید cache driver ای که مایلید به عنوان درایور پیش فرض در تمامی بخش های برنامه ی کاربردی شما مورد استفاده قرار گیرد را مشخص نمایید. Memcached و Redis دوbackend برای ذخیره سازی موقت اطلاعات (caching) هستند که با نصب لاراول به صورت آماده و از پیش تنظیم شده در اختیار توسعه دهنده قرار می گیرد.
فایل کانفیگ cache دربردارنده ی گزینه ها و آپشن های متعدد دیگری است که داخل فایل توضیحاتی برای هریک به صورت مستند ارائه شده. از این رو توصیه می کنیم تمامی این آپشن ها را کاملا مطالعه نمایید. در حالت پیش فرض فریم ورک Laravel طوری تنظیم شده که از کش درایور fileاستفاده کند. این درایور اشیا سریال (serialize) و کش شده را در filesystem ذخیره می کند. برای برنامه های تحت وب بزرگ بهتر است از کش های مقیم در حافظه (in-memory cache) نظیر Memcached یا APC بهره بگیرید.
در صورت نیاز می توانید چندین cache configuration را برای درایور یکسان تنظیم نمایید.
پیشنیاز های Cache
پایگاه داده
برای استفاده از کش درایور database لازم است یک جدول ایجاد نمایید که آیتم های کش را در خود ذخیره کند. در زیر یک تعریف schema نمونه برای این جدول مشاهده می کنید:
Schema::create('cache', function($table) {
$table->string('key')->unique();
$table->text('value');
$table->integer('expiration');
});
همچنین می توانید با اجرای دستور آرتیزان php artisan cache:table یک migration به همراه schema ی مناسب ایجاد نمایید.
Memcached
جهت استفاده از کش Memcached باید پکیج Memcached PECL را نصب نمایید.
Configuration پیش فرض از TCP/IP بر اساس Memcached::addServer بهره می گیرد:
'memcached' => [
[
'host' => '127.0.0.1',
'port' => 11211,
'weight' => 100
],
],
می توانید آپشن host را با آدرس سوکت (socket path) UNIX مقداردهی کنید. در صورت انجام این کار، بایستی آپشن port را بر نیز روی 0 تنظیم نمایید:
'memcached' => [
[
'host' => '/var/run/memcached/memcached.sock',
'port' => 0,
'weight' => 100
],
],
Redis
به منظور استفاده از کش Redis ابتدا بایستی پکیج (~1.0) predis/predis را از طریق Composer نصب کنید.
استفاده از Cache
بازیابی یک نمونه ی Cache
Contract های Illuminate\Contracts\Cache\Factory و Illuminate\Contracts\Cache\Repository به شما این امکان را می دهند تا به سرویس های cache فریم ورک Laravel دسترسی داشته باشید. کانترکت Factory امکان دسترسی به تمامی کش درایورهای اپلیکیشن را فراهم می کند. کانترکت Repository معمولا یک پیاده سازی (implementation) از کش درایور پیش فرض برنامه می باشد که توسط فایل تنظیمات cache تعیین می شود.
البته شما می توانید برای دستیابی به اهداف خود از فاساد Cache استفاده کنید. ما در آموزش حاضر از این facade در سراسر برنامه ی خود استفاده می کنیم.
فاساد Cache قابلیت دسترسی سریع و آسان به پیاده سازی های (implementation) زیرین کانترکت های cache لاراول را برای شما فراهم می سازد.
در زیر با استفاده از دستور use فاساد نام برده را در کلاس کنترلر اپلیکیشن خود وارد (import) می کنیم:
<?php
namespace App\Http\Controllers;
use Cache;
class UserController extends Controller
{
public function index()
{
$value = Cache::get('key');
//
}
}
دسترسی به چندین Cache store
پس از وارد کردن فاساد Cache در برنامه، می توانید با فراخوانی متد store همزمان به چندین cache store دسترسی داشته باشید. کلیدی که به عنوان آرگومان به متد store ارسال می گردد بایستی با یکی از store های لیست شده در آرایه ی stores موجود در فایل تنظیمات cache همخوانی داشته باشد:
$value = Cache::store('file')->get('foo');
Cache::store('redis')->put('bar', 'baz', 10);
بازیابی آیتم از Cache
متد get در فاساد Cache به منظور بازیابی آیتم هایی از cache بکار می رود. در صورتی که آیتم مورد نظر در cache وجود نداشت، مقدار null به عنوان خروجی بازگردانده می شود. در صورت تمایل می توانید یک پارامتر دوم به متد پاس دهید که مقدار پیش فرض سفارشی که مایلید در صورت یافت نشدن آیتم های دلخواه در cache به عنوان خروجی بازگردانده شود را مشخص می کند.
$value = Cache::get('key');
$value = Cache::get('key', 'default');
همچنین می توان یک تابع Closure به عنوان مقدار پیش فرض به متد یاد شده ارسال نمود. درصورتی که آیتم مورد نظر در cache موجود نبود، نتیجه ی تابع Closureبه عنوان خروجی بازیابی می شود. ارسال Closure به شما اجازه می دهد تا بازیابی مقادیر پیش فرض از پایگاه داده یا دیگر سرویس های خارجی را به تعویق بیاندازید:
$value = Cache::get('key', function() {
return DB::table(...)->get();
});
بررسی برای وجود یا عدم وجود یک آیتم
متد has را می توان برای بررسی اینکه آیا یک آیتم معین در cache وجود خارجی دارد یا نه مورد استفاده قرار داد:
if (Cache::has('key')) {
//
}
افزایش / کاهش مقادیر
توابع increment و decrement را می توان برای تنظیم مقدار آیتم هایی که در cache نوعشان عدد صحیح (integer) است، مورد استفاده قرار داد. دو تابع ذکر شده یک آرگومان اختیاری دوم دریافت می کنند که تعیین کننده ی واحد افزایش و کاهش مقدار آیتم می باشد:
Cache::increment('key');
Cache::increment('key', $amount);
Cache::decrement('key');
Cache::decrement('key', $amount);
بازیابی یا بروز رسانی
گاهی لازم می شود یک آیتم را از cache بازیابی نموده، اما همچنین در صورت عدم وجود آیتم مورد درخواست یک مقدار پیش فرض را بجای آن درcache ذخیره نمود. فرض کنید می خواهید تمامی کاربران را از cache بازیابی نمایید یا در صورت عدم وجود کاربران مورد درخواست، آن ها را از پایگاه داده واکشی کرده و در cache ذخیره کنید. برای این منظور کافی است متد Cache::remember را صدا بزنید:
$value = Cache::remember('users', $minutes, function() {
return DB::table('users')->get();
});
چنانچه آیتم مورد نظر در cache وجود نداشت، Closure ارسالی به متد remember اجرا شده و به دنبال آن نتیجه ی تابع Closure در داخلcache جایگذاری می شود.
می توان دو متد remember و forever را با هم ترکیب کرده و همزمان بکار برد:
$value = Cache::rememberForever('users', function() {
return DB::table('users')->get();
});
بازیابی و حذف آیتم
جهت بازیابی آیتم از cache و حذف آن می توان تابع pull را بکار برد. این متد نیز مانند get، در صورتی که آیتم مورد درخواست در cache یافت نشد، مقدار null را به عنوان خروجی برمی گرداند:
$value = Cache::pull('key');
ذخیره سازی آیتم ها در Cache
به منظور ذخیره ی آیتم های مورد نظر در cache، می توان تابع put را در فاساد Cache به صورت زیر فراخوانی نمود. توجه داشته باشید که به هنگام قرار دادن آیتم جدید در حافظه ی نهان (cache) بایستی تعداد دقیقه هایی را که مقدار دلخواه بایستی در آن به صورت موقت ذخیره شوند را نیز (در قالب پارامتر minutes) مشخص نمایید:
Cache::put('key', 'value', $minutes);
بجای ارسال تعداد دقایقی که باید سپری شود تا آیتم منقضی شده و از کش پاک شود، می توانید یک نمونه از DateTime پی اچ پی را به عنوان پارامتر سوم به متد ذکر شده ارسال کرد. این پارامتر تعیین کننده ی تاریخ انقضای آیتم ذخیره شده در حافظه ی نهان می باشد:
$expiresAt = Carbon::now()->addMinutes(10);
Cache::put('key', 'value', $expiresAt);
متد add تنها زمانی آیتم مورد نظر را به cache اضافه می کند که آن آیتم از قبل در حافظه ی نهان (cache store) موجود نباشد. اگر آیتم با موفقیت به cache اضافه شده باشد، متد ذکر شده مقدار بولی true را بازگردانی می نماید. در غیر این صورت این متد مقدار false را برمی گرداند:
Cache::add('key', 'value', $minutes);
با بهره گیری از تابع forever می توان یک آیتم را به صورت دائمی در cache ذخیره نمایید. مقادیری که از طریق این متد در cache ذخیره شده باشند را بایستی به صورت دستی با استفاده از متد forget حذف نمود:
حذف آیتم ها از Cache
می توانید آیتم ها را با فراخوانی متد forget در فاساد (Facade) Cache از حافظه ی نهان پاک کنید:
Cache::forget('key');
حال چنانچه مایلید کلیه ی محتویات کش را حذف نموده و آن را خالی از اطلاعات نمایید، کافی است متد flush را به صورت زیر بکار ببرید:
Cache::flush();
لازم به ذکر است که فراخوانی تابع نام برده در بالا به پیشوند کش (cache prefix) هیچ توجهی نداشته و تمامی ورودی ها را به طور کلی از آن حذف می کند. از اینرو بایستی در زمان پاک کردن کشی که بین چندین اپلیکیشن مشترک است دقت لازم را داشته باشید.
Cache tag ها (تخصیص یک تگ به آیتم های کش)
چنانچه کش درایور مورد استفاده ی اپلیکیشن file یا database است، در آن صورت دیگر امکان استفاده از Cache tag ها برای شما وجود ندارد. علاوه بر آن، زمانی که از چندین tag برای cache هایی که اطلاعات در آن ها به صورت دائمی ذخیره شده اند استفاده می کنید، توصیه می شود برای کارایی بهینه از یک درایور همچون memcached بهره گیری نمایید. این درایور به صورت خودکار رکوردهای قدیمی و بلااستفاده را حذف می کند.
ذخیره سازی آیتم های ذخیره شده در کش تگ دار
Cache tag ها به شما این امکان را می دهند تا به چندین آیتم مربوط به هم یک تگ اختصاص داده و سپس تمامی مقادیر ذخیره شده در cache را که دارای تگ یکسان می باشند به طور کلی حذف نمایید (flush نمایید). می توانید با ارسال آرایه ای مرتب از اسم تگ ها به عنوان آرگومان به یکcache تگ دار دسترسی داشته باشد. در مثال زیر به کش تگ دار دسترسی پیدا کرده و سپس با فراخوانی متد put مقداری را در کش ذخیره می کنیم:
Cache::tags(['people', 'artists'])->put('John', $john, $minutes);
Cache::tags(['people', 'authors'])->put('Anne', $anne, $minutes);
گفتنی است که شما محدود به متد put نیستید و می توانید برای کار با کش های تگ دار از هر متدی که برای ذخیره سازی اطلاعات در کش استفاده می شود، بهره گیری نمایید.
دسترسی به آیتم های ذخیره شده در کش تگ دار
به منظور بازیابی آیتم ذخیره شده در cache تگ دار (cached tag item) می توانید لیستی از اسم تگ ها را به عنوان آرگومان به متد tags پاس دهید:
$john = Cache::tags(['people', 'artists'])->get('John');
$anne = Cache::tags(['people', 'authors'])->get('Anne');
می توانید تمامی آیتم هایی که تگ یا لیستی از تگ های یکسان به آن ها اختصاص داده شده را حذف نمایید. در مثال زیر تمامی کش هایی که تگ هایpeople یا authors و یا هر دو به آن ها تخصیص داده شده، با فراخوانی دستور flush حذف می شوند. بنابراین Anne و John هر دو از حافظه ی نهان پاک می شوند:
Cache::tags(['people', 'authors'])->flush();
در مقابل، دستور زیر را داریم که در آن فقط cache هایی که با authors تگ گذاری شده اند پاک می شوند. بنابراین Anne حذف شده ولی Johnحذف نمی شود:
Cache::tags('authors')->flush();
نحوه ی اضافه کردن cache driver های سفارشی
می توان کش درایور اختصاصی خود را به لاراول اضافه نموده و بدین وسیله سرویس cache آن را گسترش داد. برای این منظور متد extend را در فاساد Cache فراخوانی می کنیم. متد مزبور یک درایور سفارشی (custom driver resolver) که به عنوان آرگومان به آن پاس داده شده را بهmanager پیوست (bind) می کند. این عملیات را معمولا داخل یک service provider انجام می دهیم.
در مثال زیر می خواهیم یک cache driver جدید به نام " mongo " را ثبت و به سرویس کش لاراول اضافه نماییم:
<?php
namespace App\Providers;
use Cache;
use App\Extensions\MongoStore;
use Illuminate\Support\ServiceProvider;
class CacheServiceProvider extends ServiceProvider
{
public function boot()
{
Cache::extend('mongo', function($app) {
return Cache::repository(new MongoStore);
});
}
public function register()
{
//
}
}
اولین آرگومان ارسالی به متد extend همان اسم درایور می باشد. این آرگومان به آپشن driver در فایل تنظیمات (config) config/cache.phpمربوط می باشد (مطابقت دارد). پارامتر ورودی دوم یک تابع Closure است که نمونه ای از Illuminate\Cache\Repository را به عنوان خروجی بازمی گرداند. به تابع Closure یک نمونه $app به عنوان آرگومان فرستاده می شود که خود نمونه ای از service container می باشد.
می توان متد Cache::extend را در boot از توابع App\Providers\AppServiceProvider پیش فرض که همراه با اپلیکیشن های تازه نصب شده ی لاراول عرضه می شود، صدا زد. همچنین می توانید service provider ویژه ی خود را ایجاد کرده و الحاقیه ی (extension) خود را، در آن معرفی نمایید. فقط باید بخاطر داشته باشید که provider را در آرایه ی provider داخل فایل config/app.php ثبت کنید.
برای ایجاد کش درایور سفارشی خود، ابتدا بایستی کانترکت (contract) Illuminate\Contracts\Cache\Store را پیاده سازی نمایید. با توجه به آنچه گفته شد، پیاده سازی کش MongoDB ما به صورت زیر خواهد بود:
<?php
namespace App\Extensions;
class MongoStore implements \Illuminate\Contracts\Cache\Store
{
public function get($key) {}
public function put($key, $value, $minutes) {}
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 (استفاده از یک MongoDB connection) می باشد. پس از اتمام پیاده سازی (implementation)، می توانیم به تکمیل فرایند ثبت درایور سفارشی (driver registration) خود بپردازیم:
Cache::extend('mongo', function($app) {
return Cache::repository(new MongoStore);
});
بعد از ایجاد الحاقیه و تکیمل آن (extension)، کافی است آپشن diver در فایل تنظیماتconfig/cache.php را با اسم الحاقیه ی جدید خود مقداردهی و بروز آوری نمایید.
Packagist مکان مناسبی برای جایگذاری کد cache driver شما می باشد. همچنین می توانید برای این منظور یک namespace به نامExtensions داخل پوشه ی app ایجاد نموده و کدهای خود را از آنجا در دسترس قرار دهید. علارغم آنچه گفته شد، Laravel خیلی سخت گیر نیست (دارای ساختار اپلیکیشن منعطف بوده) و دست شما را در سازمان دهی اپلیکیشن مطابق به میل و نیاز خود آزاد گذاشته است.
رخدادها
برای اینکه با اجرای هر عملیات کش، کد مربوط به آن نیز اجرا شود، کافی است به event های فعال شده توسط سرویس cache گوش فرا دهید. لازم به گفتن نیست که برای نیل به این هدف به Event listener نیاز دارید.
Event listener ها را معمولا داخل EventServiceProvider تعریف می کنیم:
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',
],
];