Cache

Cấu hình

Laravel cung cấp một API thống nhất cho các hệ thống cache khác nhau. Cấu hình cho cache được đặt trong file config/cache.php. Trong file này bạn có thể chỉ định cache driver nào bạn muốn sử dụng mặc định trong ứng dụng. Laravel hỗ trợ sẵn các hệ thông cache phía backends phổ biến như MemcachedRedis.

File cấu hình cache cũng chứa các tuỳ chọn khác, đều được ghi chú đầy đủ bên trong, vì thế hãy nhớ đọc kĩ chỉ dẫn trong đó. Mặc định, Laravel được cấu hình để sửa dụng cache driver là file , để lưu trữ các cache object đã được serialized trong filesystem. Với các ứng dụng lớn hơn, khuyên các bạn sử dụng in-memory cache như Memcached hay APC. Bạn thậm chí có thẻ cấu hình để sử dụng nhiều cấu hình cache cho cùng một driver.

Yêu cầu cho cache

Database

Khi sử dụng cache driver database, bạn sẽ cần thiết lập một bảng để lưu trữ các cache items. Bạn sẽ thấy một ví dụ về khai báo Schema cho bảng dưới đây:

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

Bạn cũng có thể sử dụng câu lệnh Artisan php artisan cache:table để tạo ra một migration với schema chuẩn xác.

Memcached

Sử dụng Memcached yêu cầu Memcached PECL package phải được cài đặt. Bạn có thể list tất cả Memcached servers trong file cấu hình config/cache.php:

'memcached' => [
    [
        'host' => '127.0.0.1',
        'port' => 11211,
        'weight' => 100
    ],
],

Bạn cũng có thể thiết lập thông số host tới một đường dẫn tới UNIX socket. Nếu làm thế này thì port cần được set về 0:

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

Redis

Trước khi sử dụng Redis cache với Laravel, bạn cần phải cài đặt thư viện Composer predis/predis package (~1.0).

Thông tin thêm chi tiết về cấu hình cho Redis, hãy tham khảo Laravel documentation page.

Sử dụng Cache

Lấy một đối tượng cache

Hai Illuminate\Contracts\Cache\FactoryIlluminate\Contracts\Cache\Repository contracts cung cấp truy xuất tới Laravel cache services. Contract Factory cung cấp tuy cập tới tất cả các cache drivers được khai báo cho ứng dụng. Contract Repository về cơ bản là triển khai của cache driver mặc định cho ứng dụng mà bạn chỉ định trong file cấu hình cache.

Tuy nhiên, bạn cũng có thể sử dụng Cache facade, mà bạn sẽ thấy trong suốt tài liệu này. Cache facade cung cấp cách truy xuất tiện và ngắn gọn tới các phần triển khai của các Laravel contracts:

<?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');

        //
    }
}

Truy xuất tới nhiều cache stores

Sử dụng Cache facade cho phép bạn có thể truy xuất tới nhiều cache store thông quan hàm store. Giá trị khoá truyền vào hàm store cần ứng với một trong những store danh sách các stores của mảng cấu hình trong file cấu hình cache:

$value = Cache::store('file')->get('foo');

Cache::store('redis')->put('bar', 'baz', 10);

Lấy các items trong cache

Hàm get trong Cache facade được sử dụng để lấy các items trong cache. Nếu như item không tồn tại trong cache, giá trị null sẽ được trả về. Nếu muốn, bạn có thể truyền vào tham số thứ hai để hàm get chỉ định giá trị mặc định nếu như item không tồn tại:

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

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

Bạn thậm chí có thể truyền vào một Closure như một giá trị mặc định. Kết quả của Closure sẽ được trả về nếu item cần lấy không tồn tại trong cache. Truyền vào một Closure cho phép bạn trì hoãn lại việc lấy giá trị mặc định từ trong một database hay từ một dịch vụ bên ngoài:

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

Kiểm tra item có tồn tại hay không

Hàm has có thể được sử dụng để kiểm tra xem một item có tồn tại trong cache hay không:

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

Tăng / Giảm giá trị

Hàm incrementdecrement có thể được sử dụng để điều chỉnh giá trị của các items số nguyên nằm trong cache. Cả hai hàm này có tuỳ chọn cho phép tham số thứ hai chỉ định giá trị tăng giảm bao nhiêu cho cache item:

Cache::increment('key');
Cache::increment('key', $amount);
Cache::decrement('key');
Cache::decrement('key', $amount);

Retrieve & Store

Đôi lúc bạn muốn lấy ra một item trong cache, nhưng cũng muốn lưu giá trị mặc định cho item nếu như không tồn tại. Ví dụ, bạn muốn lấy tất cả users nằm trong cache hoặc, nếu chúng không tồn tại, thì sẽ lấy từ database và thêm vào trong cache. Bạn có thể thực hiện việc này bằng cách sử dụng hàm Cache::remember:

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

Nếu item không tồn tại trong cache, thì Closure truyền vào trong hàm remember sẽ được thực thi và kết quả sẽ được lưu lại vào trong cache.

Retrieve & Delete

Nếu bạn muốn lấy ra một item trong cache và xoá đi, bạn có thể sử dụng hàm pull. Giống như hàm get, null sẽ được trả về nếu item không tồn tại trong cache từ trước đó:

$value = Cache::pull('key');

Lưu trữ items vào trong cache

Bạn có thể sử dụng hàm put của Cache facade để lưu items vào trong cache. Khi bạn thêm một item vào trong cache, bạn sẽ cần phải chỉ rõ số phút mà giá trị sẽ được lưu:

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

Thay vì truyền vào số phút cho tới khi item bị hết hạn, bạn cũng có thể truyền vào một đối tượng PHP kiểu DateTime để thể hiện thời gian hết hạn của item được cache:

$expiresAt = Carbon::now()->addMinutes(10);

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

Store If Not Present

Hàm add sẽ chỉ thêm item vào cache nếu như nó chưa tồn tại sẵn. Hàm sẽ trả về true nếu item thực sự được thêm vào cache. Còn ngược lại thì hàm sẽ trả về false:

Cache::add('key', 'value', $minutes);

Xoá các items ra khỏi cache

Hàm forever có thể được sử dụng để lưu một item trong cache vĩnh viễn. Những giá trị này cần phải được gỡ ra một cách thủ công sử dụng hàm forget:

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

Nếu bạn đang sử dụng Memcached driver, items được lưu "forever" có thể được xóa khi cache bị đầy.

Removing Items From The Cache

Bạn có thể xoá items khỏi cache sử dụng hàm forget:

Cache::forget('key');

Bạn có thể xoá toàn bộ cache sử dụng hàm flush:

Cache::flush();

iệc xoá toàn bộ cache không tuân theo tiền tố cache nào, mà sẽ thực hiện xoá toàn bộ tất cả trong cache. Vì thế hãy thực sự cẩn trọng khi xoá một giá trị cache mà được sử dụng chung giữa các ứng dụng.

The Cache Helper

Ngoài ra khi sử dụng Cache facade hoặc cache contract, bạn có thể sử dụng hàm cache để nhận và lưu dữ liệu từ cache. Khi hàmcache được gọi một mình, tham số tring, nó sẽ trả về giá trị của key:

$value = cache('key');

Nếu bạn cung cấp một mảng cặp key / value và thời gian hết hạn của hàm, nó sẽ lưu giá trị vào cache với thời gian chỉ định:

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

cache(['key' => 'value'], Carbon::now()->addSeconds(10));

Khi testing gọi hàm cache, bạn có thể dùng hàm Cache::shouldReceive như bạn dùng testing a facade.

Cache Tags

Cache tag không hỗ trợ khi sử dụng cache driver là file hoặc database. Thêm nữa, khi sử dụng nhiều tag với cache được lưu dưới dạng "forever", hiệu năng sẽ đạt tốt nhất ở driver có khả năng tự động xoá các danh sách đã lưu quá lâu như memcached.

Lưu các items đã được tag

Cache tag cho phép bạn tag các item liên quan tới nhau trong cache và có thể xoá hết các giá trị cache mà có chung một tag. Bạn có thể truy xuất vào một cache được tag bằng cách truyền vào một mảng các tên tag. Ví dụ, hãy truy cập một tagged cache và put giá trị vào cache:

Cache::tags(['people', 'artists'])->put('John', $john, $minutes);

Cache::tags(['people', 'authors'])->put('Anne', $anne, $minutes);

Truy xuất vào cache item được tag

Để lấy một cache item được tag, truyền vào danh sách tương tự các tag trong hàm tags và sau đó gọi hàm get với key bạn muốn nhận:

$john = Cache::tags(['people', 'artists'])->get('John');

$anne = Cache::tags(['people', 'authors'])->get('Anne');

Xóa Tagged Cache Items

Bạn có thể xoá tất cả các item có chung một tag hoặc danh sách các tag. Ví dụ, mã lệnh sau sẽ xoá tất cả các cache được tag với giá trị là people, authors, hoặc cả hai. Vì vậy, cả AnneJohn sẽ bị khóa khỏi cache:

Cache::tags(['people', 'authors'])->flush();

Ngược lại, câu lệnh này sẽ chỉ xoá các cache có tag là authors, vì vậy Anne sẽ bị xoá, còn John thì không:

Cache::tags('authors')->flush();

Thêm một cache driver tùy biến

Viết Driver

Để viết một tùy biến cache driver, đầu tiên chúng ta cần thực thi Illuminate\Contracts\Cache\Store contract contract. Vì vậy, MongoDB cache thực thi sẽ giống như sau:

<?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, $minutes) {}
    public function putMany(array $values, $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() {}
}

Chúng ta chỉ cần thực thi mỗi phương thức khi sử dụng kết nối MongoDB. Cho một ví dụ làm thế nào để thực thi các phương thức đó, để ý trong Illuminate\Cache\MemcachedStore. Khi chúng ta đã thực thi, chúng ta hoàn toàn có thể tùy biến đăng ký driver.

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

Nếu bạn tự hỏi khi nào put tùy biến code cache driver, bạn có thể tạo một Extensions namespace bên trong thư mục app. Tuy nhiên, hãy giữ cho Laravel không có một cấu trúc ứng dụng cứng nhắc và bạn có thể thaoir mái tổ chức theo ý của bạn.

Đăng ký Driver

Để đăng ký tùy biến cache driver với Laravel, chúng ta sử dụng hàm extend trong Cache facade. Gọi Cache::extend có thể được thực hiện trong hàm boot của App\Providers\AppServiceProvider mặc định, hoặc bạn có thể tạo tùy biến service provider để mở rộng - đừng quên dăng ký provider trong mảng config/app.php provider:

<?php

namespace App\Providers;

use App\Extensions\MongoStore;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\ServiceProvider;

class CacheServiceProvider extends ServiceProvider
{
    /**
     * Perform post-registration booting of services.
     *
     * @return  void
     */
    public function boot()
    {
        Cache::extend('mongo', function($app) {
            return Cache::repository(new MongoStore);
        });
    }

    /**
     * Register bindings in the container.
     *
     * @return  void
     */
    public function register()
    {
        //
    }
}

Tham số đầu tiên truyền vào hàm extend là tên của driver. Nó tương ứng với driver lựa chọn trong file cấu hình config/cache.php. Tham số thứ hai là một Closure that nên trả về một Illuminate\Cache\Repository instance. Closure sẽ truyền vào một $app instance, nó là instance của service container.

Khi mở rộng của bạn được đăng ký, đơn giản chỉ cần cập nhật fiel cấu hình config/cache.php giống với tên của mở rộng driver.

Events

Để thực thi code mỗi khi có một thao tác làm việc với cache xảy ra, bạn có thể lắng nghe các events từ cache. Về cơ bản, bạn nên đặt những phần này vào trong 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',
    ],
];
Nguồn: https://laravel.com/docs/5.3/cache