Học Laravel – Bài 38: Cache trong Laravel

Giới thiệu về Cache trong Laravel:

Một số tác vụ hoặc quá trình truy xuất dữ liệu có thể ngốn CPU hoặc mất nhiều thời gian để hoàn thành. Trong trường hợp này ta cần cache dữ liệu để có thể truy xuất nhanh hơn ở lần sau. Cache data thông thường lưu trữ trong Memcached hoặc Redis.

Laravel cung cấp API cho nhiều cache backend, cho phép bạn truy xuất dữ liệu nhanh chóng, tăng tốc độ ứng dụng.

Cấu hình:

Cấu hình cache trong file config/cache.php. Trong file này bạn chỉ định cache driver nào sẽ sử dụng. Laravel hỗ trợ hầu hết cache backend như memcached, redis, dynamodb. Ngoài ra cache file cũng có sẵn, còn arraynull cache driver cung cấp cách thuận tiện cho testing.

Điều kiện tiên quyết của driver:

Database:

Khi sử dụng database cache driver, bạn cần set up 1 table có chứa cache items:

Schema::create('cache', function(Blueprint $table) {
    $table->string('key')->unique();
    $table->text('value');
    $table->integer('expiration');
});

Hoặc sử dụng lệnh php artisan cache:table để tạo migration.

Memcached:

Sử dụng memcached yêu cầu Memcached PECL package được cài đặt. Cấu hình trong file config/cache.php:

'memcached' => [
    'servers' => [
        [
            'host' => env('MEMCACHED_HOST', '127.0.0.1'),
            'port' => env('MEMCACHED_PORT', 11211),
            'weight' => 100,
        ],
    ],
],

Nếu cần, bạn có thể set host option đến 1 đường dẫn UNIX socket:

'memcached' => [
    [
        'host' => '/var/run/memcached/memcached.sock',
        'port' => 0,
        'weight' => 100
    ],
],

Sử dụng cache:

Tạo 1 cache instance:

Sử dụng Cache facade:

<?php
 
namespace App\Http\Controllers;
 
use Illuminate\Support\Facades\Cache;
 
class UserController extends Controller
{
    /**
     * Show a list of all users of the application.
     */
    public function index(): array
    {
        $value = Cache::get('key');
 
        return [
            // ...
        ];
    }
}

Tiếp cận nhiều cache store:

Sử dụng Cache facade, bạn có thể tiếp cận nhiều cache store thông qua method store. Key truyền vào method store sẽ tương ứng với 1 trong những store được list trong cấu hình stores trong file config/cache.php:

$value = Cache::store('file')->get('foo');
 
Cache::store('redis')->put('bar', 'baz', 600); // 10 Minutes

Truy xuất item từ Cache:

Sử dụng method get. Nếu item không tồn tại, null được trả về. Có thể truyền tham số thứ 2 cho method để chỉ định giá trị mặc định trả về nếu item không tồn tại:

$value = Cache::get('key');
 
$value = Cache::get('key', 'default');

Bạn cũng có thể pass 1 closure, kết quả của closure sẽ được trả về làm giá trị mặc định:

$value = Cache::get('key', function () {
    return DB::table(/* ... */)->get();
});

Xác minh 1 item có tồn tại:

if (Cache::has('key')) {
    // ...
}

Tăng / Giảm giá trị:

Dùng method incrementdecrement:

// Initialize the value if it does not exist...
Cache::add('key', 0, now()->addHours(4));
 
// Increment or decrement the value...
Cache::increment('key');
Cache::increment('key', $amount);
Cache::decrement('key');
Cache::decrement('key', $amount);

Truy xuất và lưu trữ:

Thi thoảng bạn cần truy xuất item và đồng thời lưu trữ 1 giá trị mặc định nếu item được yêu cầu không tồn tại. Ví dụ, bạn cần truy xuất tất cả users từ cache, nếu không tồn tại, truy xuất từ database và add vào cache. Sử dụng Cache::remember method:

$value = Cache::remember('users', $seconds, function () {
    return DB::table('users')->get();
});

Sử dụng method rememberForever để lưu trữ vĩnh viễn.

Lưu trữ item vào cache:

Sử dụng method put:

Cache::put('key', 'value', $seconds = 10);

Nếu tham số thời gian không được truyền vào, item sẽ được cache vĩnh viễn:

Cache::put('key', 'value');

Bạn cũng có thể pass 1 DateTime instance để lưu thời gian hết hạn của cache:

Cache::put('key', 'value', now()->addMinutes(10));

Gỡ item khỏi cache:

Sử dụng method forget:

Cache::forget('key');

Xóa toàn bộ cache sử dụng method flush:

Cache::flush();

Lưu ý: flush cache sẽ gỡ toàn bộ dữ liệu ra khỏi cache. Cẩn thận khi xóa cache mà được share chung bởi ứng dụng khác.

Cache Helper:

Sử dụng global function cache():

$value = cache('key');

cache(['key' => 'value'], $seconds);
 
cache(['key' => 'value'], now()->addMinutes(10));

cache()->remember('users', $seconds, function () {
    return DB::table('users')->get();
});

Thêm Custom Cache Drivers:

Viết driver:

Để tạo custom cache driver, cần implement Illuminate\Contracts\Cache\Store:

<?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() {}
}

Để xem ví dụ cụ thể về cách implement các method trên, xem ví dụ Illuminate\Cache\MemcachedStore trong source code Laravel.

Sử dụng custome driver bằng method extend:

Cache::extend('mongo', function (Application $app) {
    return Cache::repository(new MongoStore);
});

Đăng ký Driver:

Để đăng ký custom cache driver, sử dụng method extend trên Cache facade. Vì những service providers khác có thể đọc cache trong method boot, chúng ta sẽ đăng ký custom driver trong callback booting. Bằng cách này, custom driver sẽ được đăng ký trước method boot nhưng sau method register:

<?php
 
namespace App\Providers;
 
use App\Extensions\MongoStore;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\ServiceProvider;
 
class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     */
    public function register(): void
    {
        $this->app->booting(function () {
             Cache::extend('mongo', function (Application $app) {
                 return Cache::repository(new MongoStore);
             });
         });
    }
 
    /**
     * Bootstrap any application services.
     */
    public function boot(): void
    {
        // ...
    }
}

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *