Trước đây, chúng ta bị giới hạn cast mặc định do Laravel cung cấp. Mặc dù, có một số gói thư viện có thể  giúp chúng ta custom được nhưng chúng có một nhược điểm lớn. Bởi vì, chúng ghi đề phương thức setAttribute và getAttribute thông qua trait, chúng không thể sử dụng bất kì một gói thư viện nào khác vì chúng cũng ghi đè phương thức đó.

Giờ đây, Laravel đã hỗ trợ phần custom cast, sẽ không xảy ra vấn đề như không tương thích giữa các thư viện nữa. Để hiểu rõ hơn về Laravel Custom Eloquent Casts chúng ta hãy thực hiện một số ví dụ đơn giản như sau.

Để khai báo một Custom Eloquent Casts:

Chúng ta cần implement interface CastsAttributes có chứa 2 phương thức get và set dùng để get giá trị và set giá trị cho các attribute.

Đầu tiên, chúng ta sẽ tạo một file tên là EncryptCast.php nằm ở thư mục app/Casts, phần tạo này các bạn hãy bằng tay vì Laravel chưa cung cấp lệnh command để tạo file một cách tự động.

Sau đó bạn hãy mở file EncryptCast.php và chỉnh sửa như sau:

<?php

namespace App\Casts;

use Illuminate\Contracts\Database\Eloquent\CastsAttributes;

class EncryptCast implements CastsAttributes
{
    /**
     * Cast the given value.
     *
     * @param  \Illuminate\Database\Eloquent\Model  $model
     * @param  string  $key
     * @param  mixed  $value
     * @param  array  $attributes
     * @return array
     */
    public function get($model, $key, $value, $attributes)
    {
        return decrypt($value);
    }

    /**
     * Prepare the given value for storage.
     *
     * @param  \Illuminate\Database\Eloquent\Model  $model
     * @param  string  $key
     * @param  array  $value
     * @param  array  $attributes
     * @return string
     */
    public function set($model, $key, $value, $attributes)
    {
        return [$key => encrypt($value)];
    }
}

Trong Model (ở đây mình sử dụng Model User), chúng ta sẽ set thuộc tính password sử dụng Custom Cast mà chúng ta vừa tạo ở trên như sau:

<?php

namespace App\Models;

use App\Casts\EncryptCast;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * The attributes that should be cast.
     *
     * @var array
     */
    protected $casts = [
        'password' => EncryptCast::class,
    ];
}

Bây giờ, chúng ta hãy trải nghiệm cách hoạt động của Laravel Custom Cast ở một controller bất kỳ nào.

/**
 * Show the form for creating a new resource.
 *
 * @return \Illuminate\Http\Response
 */
public function create()
{
    $user = User::first();
    $user->password = 'ManhDanBlogs';
    $user->save();      
    // Giá trị được mã hóa (sẽ được lưu vào database)
    // Raw value : eyJpdiI6IjI1dE9RMGFQUktjeTk5aTVIQWlSNX....
    dd($user->getAttributes()['password']);
    // Giá trị chưa được mã hóa
    dd($user->password);
}

Đôi khi, bạn chỉ muốn format giá trị đang set trên model và không thực hiện bất kỳ xử lý nào khi chúng ta truy xuất dữ liệu từ model.

Vì vậy, chúng ta nên sử dụng interface CastsInboundAttributes, vì nó chỉ yêu cầu bắt buộc duy nhất là hàm set.

Ví dụ, bạn muốn giới hạn độ dài của string khi thực hiện set giá trị trong model.

Đầu tiên, chúng ta sẽ tạo một file tên là LimitCaster.php nằm ở thư mục app/Casts và chỉnh sửa như sau:

<?php

namespace App\Casts;

use Illuminate\Support\Str;
use Illuminate\Contracts\Database\Eloquent\CastsInboundAttributes;

class LimitCaster implements CastsInboundAttributes
{
     /**
     * Create a new cast class instance.
     *
     * @param  string|null  $algorithm
     * @return void
     */
    public function __construct($length = 25)
    {
        $this->length = $length;
    }

    /**
     * Prepare the given value for storage.
     *
     * @param  \Illuminate\Database\Eloquent\Model  $model
     * @param  string  $key
     * @param  array  $value
     * @param  array  $attributes
     * @return string
     */
    public function set($model, $key, $value, $attributes)
    {
        return [$key => Str::limit((string) $value, $this->length)];
    }
}

Trong Model (ở đây mình sử dụng Model User), chúng ta sẽ set thuộc tính name sử dụng Custom Cast mà chúng ta vừa tạo ở trên như sau:

<?php

namespace App\Models;

use App\Casts\LimitCaster;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * The attributes that should be cast.
     *
     * @var array
     */
    protected $casts = [
       name' => LimitCaster::class . ':7'
    ];
}

Bây giờ, chúng ta hãy trải nghiệm cách hoạt động của nó ở một controller bất kỳ nào.

/**
 * Show the form for creating a new resource.
 *
 * @return \Illuminate\Http\Response
 */
public function create()
{
    $user = User::first();
    $user->name = 'ManhDanBlogs';
    $user->save();      
    // Value: ManhDan...
    dd($user->name);
}

Như vậy, chúng ta đã thực hiện xong một ví dụ đơn giản về Laravel Custom Cast, tôi hy vọng hướng dẫn của tôi sẽ giúp ích cho công việc của bạn. Nếu bạn có bất kỳ câu hỏi nào hãy liên hệ với chúng tôi qua trang contact. Cảm ơn bạn.

CÓ THỂ BẠN QUAN TÂM

How to insert into a database at lightning speed?

How to insert into a database at lightning speed?

Trong quá trình thực hiện dự án cho công ty, một trong những yêu cầu đặt ra là import dữ liệu từ file CSV (chứa dữ liệu từ hệ thống cũ) vào cơ sở dữ liệu MySQL của hệ thống mới. Do sự thay đổi cấu...

Pipeline Design Pattern in Laravel

Pipeline Design Pattern in Laravel

Pipeline Design Pattern là nơi mà các dữ liệu được chuyển qua một chuỗi các nhiệm vụ hoặc giai đoạn. Pipeline hoạt động giống như một chuỗi dây chuyền lắp ráp, nơi dữ liệu được xử lý và sau đó, sẽ...

Laravel Validate Video Duration

Laravel Validate Video Duration

Đôi khi trong dự án, chúng ta cần xác định thời lượng video được phép upload lên server. Nhưng rất tiếc, Laravel không cung cấp validate xác định thời lượng video để chúng ta thực hiện được. Vì vậy, t...

Implementing Private User Folders with CKFinder in Laravel

Implementing Private User Folders with CKFinder in Laravel

CKFinder 3 CKFinder 3 là trình quản lý tập tin được tích hợp với CKEditor 4 và CKEditor 5. Nó giúp bạn dễ dàng đưa các tập tin và hình ảnh vào nội dung của Editor một cách an toàn. Đây là một tín...

Laravel Socialite Login With Linkedin

Laravel Socialite Login With Linkedin

LinkedIn LinkedIn là mạng xã hội tập trung vào mạng lưới nghề nghiệp và phát triển nghề nghiệp và chuyên nghiệp lớn nhất thế giới trên internet. Bạn có thể sử dụng LinkedIn để tìm công việc hoặc...

Google Drive as Filesystem in Laravel

Google Drive as Filesystem in Laravel

Đối với một số dự án, bạn cần phải sử dụng Google Drive (với tài khoản @gmail.com cá nhân hoặc tài khoản G Suite) làm nhà cung cấp bộ nhớ trong các dự án Laravel. Trong bài đăng này, tôi sẽ hướng d...

Export CSV from AWS RDS - Import into MySQL with Laravel

Export CSV from AWS RDS - Import into MySQL with Laravel

Transfer Database Trong quá trình phát triển và bảo trì dự án, nhiệm vụ di chuyển cơ sở dữ liệu từ hệ thống này sang hệ thống khác là một nhiệm vụ khá là phổ biến. Chúng ta thường sẽ sử dụng câu...

Export CSV from SQL Server - Import into MySQL with Laravel

Export CSV from SQL Server - Import into MySQL with Laravel

Transfer Database Trong quá trình phát triển và bảo trì dự án, việc di chuyển cơ sở dữ liệu từ hệ thống này sang hệ thống khác là một nhiệm vụ khá phổ biến. Giả sử bạn cần di chuyển dữ liệu từ SQ...

Integrating Google Gemini AI in Laravel

Integrating Google Gemini AI in Laravel

Google Gemini Gemini là một mô hình trí tuệ nhân tạo mới mạnh mẽ từ Google không chỉ có khả năng hiểu văn bản mà còn có thể hiểu cả hình ảnh, video và âm thanh. Gemini là một mô hình đa phương ti...

ManhDanBlogs