اذهب إلى المحتوى

أساسيات التخبئة Cache في Laravel


محمد أحمد العيل

يوفّر Laravel واجهة تطبيقات برمجية موّحدة للتعامل مع أنظمة تخبئة Cache مختلفة مثل Memcached وRedis.

سنعرض في هذا المقال لكيفية إعداد التخبئة في Laravel ومبدأ عملها ثم نتطرق للدالة المساعدة cache التي أضيفت إلى إطار العمل بداية من الإصدار 5.3.

laravel-cache.png

تهيئة بيئة التطوير

يُحدَّد اسم النظام المستخدَم في التعليمة CACHE_DRIVER ضمن ملف env.. تأخذ التعليمة CACHE_DRIVER مبدئيا القيمة file التي تعني أن الكائنات Objects المخبَّأة ستخزن ضمن ملف ضمن نظام التشغيل. تُضبَط إعدادات نظام التخبئة المستخدَم في الملف config/cache.php، بعد تعيينه بالتعليمة السابقة.

نفترض أنك لديك مشروع Laravel بالإصدار 5.3 للتطبيق عليه. ننفذ الخطوات التالية لتهيئة مثال نعتمد عليه في ما بعد للشرح.

إنشاء نموذج والتهجير المصاحب له وبذره

نستخدم artisan لإنشاء نموذج Eloquent مع التهجير المصاحب له على النحو التالي:

php artisan make:model Post -m

نفتح ملف التهجير لضبط الحقول في جدول البيانات بإضافة حقل جديد يُسمّىtitle (العنوان):

public function up()
{
    Schema::create('posts', function (Blueprint $table) {
        $table->increments('id');
        $table->string("title");
        $table->timestamps();
    });
}

يمكننا الآن تنفيذ التهجير:

php artisan migrate

الخطوة التالية هي بذر الجدول الحصول على بيانات للتطبيق عليها. ننشئ ملف البذر:

php artisan make:seeder PostsTableSeeder

ثم نعدل عليه:

class PostsTableSeeder extends Seeder
{
    public function run()
    {
    Model::unguard();

    // نستورد faker لبذر الجدول
    $faker = Faker\Factory::create();

    // ننشئ 10 تسجيلات في الجدول
    foreach(range(1, 10) as $index) {
        Post::create([
            'title' => $faker->sentence(5),
        ]);
    }

    Model::reguard();
    }
}

نعدّل ملف بذر قاعدة البيانات لإضافة ملف بذر الجدول posts إليه:

public function run()
{
    $this->call(PostsTableSeeder::class);
}

ثم ننفذ البذر:

php artisan db:seed --class=PostsTableSeeder

لدينا الآن جدول بيانات بـ10 تسجيلات. أكملنا إعداد النموذج الذي نريد العمل عليه، الخطوة الموالية هي إعداد المتحكم والمسارات.

المتحكم والمسارات

نستعين بأداة artisan لإنشاء متحكم على النحو التالي:

 
php artisan make:controller PostsController

ننشئ في المتحكم PostsController دالة باسم index نستخدمها للحصول على جميع المنشورات الموجودة في جدول البيانات posts بصيغة JSON:

public function index() {
    $posts = Post::all();
    return response()->json($posts);
}

لا تنس استيراد النموذج Post:

 
use App\Post;

ثم ننتقل إلى إعداد المسارات. سنضيف مسارا باسم posts/ إلى ملف مسارات واجهةالوب routes/web.php:

 
Route::get('/posts', 'PostsController@index');

يمكننا الآن تنفيذ الأمر php artisan serve من مجلد المشروع لتشغيل الخادوم الخاص ببيئة التطوير ثم الذهاب إلى الرابط http://localhost:8000/posts لرؤية جميع المنشورات المحفوظة في الجدول.

إعداد التخبئة واستخدامها

تُضبَط التخبئة - كما أسلفنا - في الملفين env. وconfig/cache.php. يحوي الصنف Illuminate\Support\Facades\Cache الكثير من الدوال الثابتة Static التي تتعامل مع التخبئة.

إضافة قيمة إلى التخبئة

تُستخدَم الدالة Cache::put لإضافة قيمة إلى التخبئة. تأخذ الدالة ثلاثة معطيات:

Cache::put('key', 'value', 10);
  • مفتاح key يمثل اسم المتغير. لا يمكن أن تحمل قيمتان في النظام نفس المفتاح.
  • قيمة المفتاح value.
  • مدة زمنية معبَّر عنها بالدقائق (10 في المثال أعلاه)، وتمثل المدة التي سيحتفظ النظام فيها بقيمة المفتاح ضمن التخبئة.

تمكن أتمتة إضافة المفاتيح إلى التخبئة بالدالة remember. تبحث هذه الدالة أولا عن قيمة المفتاح في التخبئة، وترجعها إن وجدته؛ فإن لم تجده تنشئ المفتاح وتعطيه القيمة التي ترجعها دالة الإغلاق Closure الممررة في المعطى الثالث.
سنستخدم الدالة remember في دالة index التي أضفناها سابقا إلى المتحكم. نعدّل الدالة index على النحو التالي:

public function index() {
    $posts = Cache::remember('posts', 5, function() {
        return Post::all();
    });
    return response()->json($posts);
}

لا ننسى استدعاء الصنف Cache:

 
use Illuminate\Support\Facades\Cache;

تعني الشفرة أعلاه أننا عند طلب الدالة index فإنها ستبحث عن المنشورات الموجودة في التخبئة، فإن وجدتها ترجعها وإلا فإنها تنشئها باستدعاء الدالة all من النموذج Post؛ وتحتفظ بها في التخبئة لمدة خمس دقائق؛ ثم ترجع النتيجة.

بهذا تكون جميع الطلبات التي ترد إلى المسار posts/ تمر عبر التخبئة؛ سنضيف لأغراض التوضيح مسارا جديدا (ضمن routes/web.php) لنعدل عن طريقه على إحدى التسجيلات الموجودة في جدول المنشورات:

 
Route::get('/edit/post/{id}', 'PostsController@edit');

ونعدّل المتحكم بإضافة الدالة edit التالية:

public function edit($id) {
    $post = Post::find($id);
    $post->title = "New title for ".$id;
    $post->save();
    $posts = Post::all();
    return response()->json($posts);
}

ما يحدث هو التالي: تظهر عند زيارة الرابط posts/ المنشورات مع المرور على نظام التخبئة؛ أما عند زيارة المسار edit/post/id/ فسنعدّل على المنشور ذي المعرف id، ثم نعرض المنشورات المخزنة في الجدول مباشرة، دون البحث عنها في التخبئة.

يظهر في الصورة المتحركة التالية الفرق بين استخدام التخبئة وطلب المنشورات مباشرة من الجدول:

01_laravel_cache.gif

  • تكون التخبئة فارغة عند زيارة المسار posts/ لأول مرة. في هذه الحالة يطلب Laravel المنشورات مباشرة من جدول البيانات، يعرضها ثم يضيفها إلى التخبئة.
  • نطلب الرابط edit/post/1/ الذي يغيّر عنوان المنشور ذي المعرف 1 ليصبح New title for 1؛ ثم يعرض المنشورات بطلبها مباشرة من جدول قاعدة البيانات. لاحظ تغير عنوان المنشور.
  • نعود للرابط posts/ قبل انقضاء المدة المحددة في دالة التخبئة (5 دقائق)، نلاحظ أن التعديل الذي أجريناه لا يظهر في المنشورات المعروضة.

ملحوظة: يجب التأكد في التطبيقات الموجهة لبيئة الإنتاج من تناسق عمليات التعديل على قاعدة البيانات والتخبئة. بمعنى أنه يجب أن ينعكس التعديل على قيمة في جدول البيانات مباشرة على القيمة المحفوظة في التخبئة.

العمليات على التخبئة

  • الحصول على قيمة من التخبئة:

    Cache::get('key');

    يمكن إرجاع قيمة مبدئية في حال عدم وجود المفتاح في التخبئة:

    Cache::get('key', 'default');

    تبحث الدالة أعلاه عن قيمة المفتاح key في التخبئة، فإن لم تجدها ترجع القيمة المبدئية default.

  • التحقق من وجود مفتاح في التخبئة:

    if (Cache::has('key')){
        Cache::get('key');
    } else {
        Cache::put('key', $values, 10);
    }

    نتحقق في الشفرة أعلاه من وجود قيمة للمفتاح key ونرجعها إن وجدت؛ وإلا نضيف قيمة جديدة للمفتاح في التخبئة.

  • نزع مفتاح من التخبئة:

     
    Cache::forget('key');

    كما يمكن استخدام الدالة pull التي تبحث عن قيمة في التخبئة، ثم تحذفها بعد الحصول عليها:

    Cache::pull('key');

    يشبه الأمر تنفيذ الدالتين get وforget بالتتالي.

    توجد طريقة أخرى لحذف محتوى التخبئة قبل انتهاء المدة المحددة له بتنفيذ أمر artisan التالي:

    php artisan cache:clear

     

الدالة المساعدة cache

يحتوي إطار العمل Laravel على الكثير من دوال PHP المساعدة؛ بعضها مستخدَم في وظائف إطار العمل نفسه. تعمل الدوال المساعدة Helper functions على الرفع من الإنتاجية والابتعاد عن تكرار الشفرات البرمجية بتجميع وظائف اعتيادية وإتاحة الوصول إليها حيث دعت الحاجة.
يضيف الإصدار 5.3 دالة مساعدة جديدة باسم cache يمكن استخدامها في أي جزء من المشروع من أجل تسهيل التخاطب مع نظام التخبئة، بدلا من الصّنف Illuminate\Support\Facades\Cache.

نحصل على قيمة المتغير key (المفتاح) باستخدام الدالة المساعدة cache على النحو التالي:

cache('key');

تكافئ التعليمة أعلاه استخدام الصنف Cache على النحو التالي:

Cache::get('key');

يمكن أيضا تمرير مصفوفة بالمفاتيح وقيمها إلى الدالة cache؛ ونحدّد المدة الزمنية التي نريد أن تستغرقها التخبئة:

cache(['title' => 'Hsoub Academy'], 5);

إن طلبنا في الخمس دقائق القادمة قيمة المفتاح title في الدالة cache فسنجد القيمة Hsoub Academy.

نستخدم الدوال الموجودة في الصنف Cache في الدالة المساعدة cache بنفس الطريقة:

  • إضافة مفتاح إلى التخبئة:

    cache()->put('key', 'value', 10);

    أو

     
    cache(['key' => 'value'],10);

    البحث عن قيمة المفتاح في التخبئة، وإضافته إليها إن لم يوجد بها:

    cache()->remember('key', 5, function() {
        //
    });

     

  • الحصول على قيمة مفتاح من التخبئة ثم حذفه منها بعد ذلك:

    cache()->pull('key');

     

  • حذف مفتاح من التخبئة:

    cache()->forget('key');

     

نعيد كتابة الدالة index في المتحكم PostsController بالدالة المساعدة cache بدلا من الصنف Cache:

public function index() {

    $posts = cache()->remember('posts', 5, function() {
        return Post::all();
    });
    return response()->json($posts);

}

يمكن ملاحظة أنك لا تحتاج لاستيرد صنف جديد؛ فالدالة المساعدة متوفرة في جميع المشروع.


تفاعل الأعضاء

أفضل التعليقات

لا توجد أية تعليقات بعد



انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أضف تعليق

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • أضف...