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

Generate PDF with Header and Footer on every page in Laravel

Generate PDF with Header and Footer on every page in Laravel

Hôm nay, trong bài viết này mình sẽ chia sẻ với các bạn cách dompdf mà header và footer sẽ được hiển thị ở tất cả các trang. Đây cũng là một vấn đề khá phổ biến, khi chúng ta phát triển các tính năng...

Integrating TinyMCE in Laravel 10 using Vite

Integrating TinyMCE in Laravel 10 using Vite

TinyMCE TinyMCE là một trình soạn thảo WYSIWYG được xây dựng trên nền tảng Javascript, được phát triển dưới dạng mã nguồn mở theo giấy phép MIT bởi Tiny Technologies Inc. TinyMCE cho phép ngư...

Amazon S3 Pre-Signed URL with DropzoneJs in Laravel

Amazon S3 Pre-Signed URL with DropzoneJs in Laravel

Chức năng upload file hay hình ảnh là một chức năng rất phổ biến, hầu hết các dự án đều có chức năng này. Đa số các nhà phát triển khi thực hiện chức năng upload file, thường sẽ sử dụng cách làm nh...

Easy Laravel Reverb Setup For Beginners

Easy Laravel Reverb Setup For Beginners

Laravel Reverb Lần đầu tiên, Laravel ra mắt một official package cho phép bạn xây dựng một Websocket Server. Trước đây, chúng ta phải sử dụng package bên thứ 3 như Laravel Websocket. Reverb được...

Laravel One to Many Eloquent Relationship

Laravel One to Many Eloquent Relationship

One to Many Relationship được sử dụng trong trường hợp một dữ liệu của một bảng được liên kết với một hoặc nhiều dữ liệu ở bảng khác. Ví dụ, một bài post có thể có nhiều comment. Vì vậy, trong hướn...

How To Optimize Your Site With GZIP Compression

How To Optimize Your Site With GZIP Compression

GZIP là công nghệ nén thường được sử dụng để truyền dữ liệu một cách nhanh chóng qua Insternet. Hiện nay, GZIP là một tiêu chuẩn để nén các file trên trang web, đa số các website hiện nay hơn 99% sử d...

Laravel Migration

Laravel Migration

Migration cho phép các nhà phát triển (Developer) nhanh chóng tạo ra cở sở dữ liệu của ứng dụng mà không cần vào màn hình quản lý cơ sở dữ liệu hay chạy bất kì một câu lệnh SQL nào. Trước hết, nếu...

Laravel Change Expire Time Cookie Remember

Laravel Change Expire Time Cookie Remember

Vấn đề Đôi khi, trang web của bạn chỉ muốn người dùng sử chức năng remembering users  trong 7 ngày hoặc là 30 ngày chẳng hạn. Nhưng Authentication của Laravel không cung cấp cho chúng ta tùy chọn đ...

Document Laravel API With OpenAPI (Swagger)

Document Laravel API With OpenAPI (Swagger)

Swagger là gì? Swagger là một Ngôn ngữ mô tả giao diện để mô tả các API RESTful được thể hiện bằng JSON. Swagger được sử dụng cùng với một bộ công cụ phần mềm mã nguồn mở để thiết kế, xây dựng, l...

ManhDanBlogs