Migration PHP Attributes Laravel 13: Hướng Dẫn Chi Tiết

Nội dung

Cách chuyển đổi từ protected properties sang PHP Attributes trong Laravel 13 với hướng dẫn từng bước và code examples chi tiết.
Migration PHP Attributes Laravel 13
Hướng dẫn migration PHP Attributes trong Laravel 13

Tóm tắt nhanh

  • PHP Attributes thay thế protected properties trong Laravel 13
  • Hỗ trợ Models, Jobs, Commands, Controllers, và nhiều hơn nữa
  • Hoàn toàn backward compatible – không cần viết lại code cũ
  • Chiến lược migration: từng bước nhỏ, không refactor một lúc
  • Có thể mix giữa properties và attributes trong cùng một file

Cài đặt yêu cầu trước khi migration

Để sử dụng PHP Attributes trong Laravel 13, bạn cần PHP 8.3 trở lên và Laravel 13. Đây là yêu cầu bắt buộc – nếu server của bạn vẫn đang chạy PHP 8.2, hãy nâng cấp lên PHP 8.3 trước.

Để kiểm tra phiên bản PHP hiện tại, bạn chạy:

php -v

Nếu bạn chưa nâng cấp lên Laravel 13, hãy xem bài viết Laravel 13 có gì mới để biết thêm chi tiết về quá trình nâng cấp.

Model Attributes – Eloquent Models

PHP Attributes trong Eloquent Models cho phép bạn khai báo cấu hình model trực tiếp trên class thay vì dùng protected properties. Đây là thay đổi lớn nhất và mang lại visual improvement rõ rệt nhất.

Cách chuyển đổi Model

Trước đây với Laravel 12 trở xuống, bạn viết:

class User extends Model
{
    protected $table = 'system_users';
    protected $primaryKey = 'user_id';
    public $incrementing = false;
    protected $keyType = 'string';
    protected $fillable = ['name', 'email'];
    protected $hidden = ['password', 'remember_token'];
}

Với Laravel 13, bạn có thể viết gọn gàng hơn:

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Attributes\Table;
use Illuminate\Database\Eloquent\Attributes\Fillable;
use Illuminate\Database\Eloquent\Attributes\Hidden;

#[Table('system_users', key: 'user_id', keyType: 'string', incrementing: false)]
#[Fillable(['name', 'email'])]
#[Hidden(['password', 'remember_token'])]
class User extends Model
{
    // Class body trống - không còn boilerplate!
}

Danh sách đầy đủ Model Attributes

  • #[Table(‘table_name’)] — thay thế protected $table
  • #[PrimaryKey(‘column’)] — thay thế protected $primaryKey
  • #[KeyType(‘string’)] — thay thế protected $keyType
  • #[Fillable([‘columns’])] — thay thế protected $fillable
  • #[Guarded([‘columns’])] — thay thế protected $guarded
  • #[Unguarded] — mới, không có property tương đương
  • #[Hidden([‘columns’])] — thay thế protected $hidden
  • #[Visible([‘columns’])] — thay thế protected $visible
  • #[Appends([‘accessors’])] — thay thế protected $appends
  • #[Touches([‘relations’])] — thay thế protected $touches
  • #[Connection(‘name’)] — thay thế protected $connection

Job Attributes – Queue Jobs

Queue Jobs cũng được hỗ trợ PHP Attributes đầy đủ, giúp cấu hình job behavior trở nên declarative và dễ đọc hơn.

Trước đây:

class ProcessOrder implements ShouldQueue
{
    public $connection = 'redis';
    public $queue = 'orders';
    public $tries = 3;
    public $timeout = 120;
}

Với Laravel 13:

use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\Attributes\Connection;
use Illuminate\Queue\Attributes\Queue;
use Illuminate\Queue\Attributes\Tries;
use Illuminate\Queue\Attributes\Timeout;

#[Connection('redis')]
#[Queue('orders')]
#[Tries(3)]
#[Timeout(120)]
class ProcessOrder implements ShouldQueue
{
    // Logic của job
}

Một số Job Attributes hữu ích khác:

  • #[Backoff([10, 60, 300])] — cấu hình thời gian chờ giữa các lần retry
  • #[MaxExceptions(3)] — số exception tối đa trước khi đánh dấu failed vĩnh viễn
  • #[FailOnTimeout] — đánh dấu job failed nếu timeout
  • #[WithoutOverlapping] — không chạy song song với các job cùng loại

Command Attributes – Artisan Commands

Console Commands cũng được hưởng lợi từ PHP Attributes, cho phép khai báo signature và description trực tiếp trên class.

Trước đây:

class SyncDataCommand extends Command
{
    protected $signature = 'sync:data {provider?}';
    protected $description = 'Sync data from external provider';
}

Với Laravel 13:

use Illuminate\Console\Command;
use Illuminate\Console\Attributes\Signature;
use Illuminate\Console\Attributes\Description;

#[Signature('sync:data {provider?}')]
#[Description('Sync data from external provider')]
class SyncDataCommand extends Command
{
    // Logic của command
}

Controller Attributes

Laravel 13 bổ sung hai controller attributes quan trọng: #[Middleware] và #[Authorize].

Trước đây bạn phải viết:

class UserController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth');
        $this->middleware('admin')->only(['destroy']);
    }
}

Với Laravel 13, bạn có thể viết gọn hơn:

use Illuminate\Routing\Controller;
use Illuminate\Routing\Attributes\Middleware;
use Illuminate\Routing\Attributes\Authorize;

#[Middleware('auth')]
class UserController extends Controller
{
    #[Middleware('admin')]
    #[Authorize('delete-users')]
    public function destroy($id)
    {
        // Logic
    }
}

Chiến lược Migration thực tế

Không cần refactor tất cả cùng lúc. Hãy tiếp cận từ từ theo từng bước nhỏ.

Bước 1: Bắt đầu với model mới

Khi bạn tạo model mới trên Laravel 13, hãy sử dụng attributes ngay từ đầu. Đây là cách dễ nhất để áp dụng mà không ảnh hưởng đến code hiện có.

Bước 2: Convert khi đã chạm vào file

Khi bạn đang fix bug hoặc thêm feature cho một model cũ, hãy dành 5-10 phút để chuyển đổi sang attributes. Đừng refactor cả 50 models trong một PR – team sẽ khó review và nếu có lỗi, bạn sẽ không biết model nào gây ra.

Bước 3: Sử dụng IDE hỗ trợ

PhpStorm và VS Code với Intelephense đều hỗ trợ auto-import attributes. Khi bạn gõ tên attribute, IDE sẽ tự động thêm use statement.

Bước 4: Mix properties và attributes

Hệ thống hoàn toàn backward compatible. Bạn có thể dùng #[Table(‘users’)] nhưng vẫn giữ protected $fillable. Laravel sẽ resolve cả hai.

Tuy nhiên, nên chọn một style nhất quán cho mỗi file để code dễ đọc hơn.

Checklist Migration

Dưới đây là checklist từng bước để migration một file sang PHP Attributes:

  1. Đảm bảo PHP 8.3+ đang chạy (php -v)
  2. Đảm bảo Laravel 13 đã được cài đặt
  3. Chọn một file để migration (model, job, hoặc command)
  4. Thêm các use imports cần thiết cho từng attribute
  5. Di chuyển từng property sang attribute tương ứng
  6. Test để đảm bảo không có lỗi
  7. Commit với message rõ ràng, ví dụ: “refactor: convert User model to PHP Attributes”

Về performance, theo đánh giá từ cộng đồng Laravel [1], reflection trong PHP không có overhead đáng kể như nhiều người lo ngại. Attribute resolution xảy ra một lần khi application bootstrap, không ảnh hưởng đến request handling.

Nguồn tham khảo

  1. Laravel 13 PHP Attributes: A Practical Guide – Hafiz Riaz
  2. PHP Attributes in Laravel 13: The Ultimate Guide – Laravel Daily
  3. Laravel 13 PHP Attributes: Refactor in 10 Minutes – DEV Community
  4. Laravel 13 Deep Dive – DEV Community
  5. Laravel 13 Released – Laravel News

Các câu hỏi thường gặp

Tôi có bắt buộc phải dùng PHP Attributes không?

Không. PHP Attributes hoàn toàn tùy chọn. Laravel 13 backward compatible 100% – code cũ với protected properties vẫn hoạt động bình thường.

Tôi có thể mix properties và attributes trong cùng một model không?

Có thể. Bạn có thể dùng #[Table(‘users’)] nhưng vẫn giữ protected $fillable. Laravel sẽ resolve cả hai. Tuy nhiên, nên chọn một style nhất quán cho mỗi file.

PHP Attributes có ảnh hưởng đến performance không?

Không đáng kể. Reflection trong PHP không có overhead lớn như nhiều người lo ngại. Attribute resolution xảy ra một lần khi application bootstrap.

Laravel Shift có hỗ trợ migration tự động không?

Laravel Shift sẽ sớm cung cấp tính năng chuyển đổi tự động từ properties sang attributes. Tuy nhiên, vì đây là thay đổi tùy chọn, bạn có thể tự migrate theo tốc độ của mình.

Tôi nên bắt đầu migration từ đâu?

Bắt đầu với các model mới, sau đó convert các model cũ khi bạn đã chạm vào chúng để fix bug hoặc thêm feature. Không nên refactor tất cả cùng lúc.

Bạn đã thử migration sang PHP Attributes chưa? Chia sẻ kinh nghiệm nhé! Nếu có câu hỏi, để lại comment — mình sẽ hỗ trợ!

Tú Anh

Cây bút chính tại VietnamTutor

Bài viết cùng chuyên mục

Git reset revert restore: chọn lệnh đúng

Bài viết so sánh git reset, git revert và git restore theo mục đích sử dụng: sửa staging area, khôi phục file, undo commit chưa push

Git commit vào nhánh sai: cách chuyển an toàn

Bài viết hướng dẫn xử lý git commit vào nhánh sai theo từng tình huống: commit chưa push, đã push, nhiều commit liên tiếp hoặc branch

TypeScript cho website doanh nghiệp: API, form và lỗi

TypeScript cho website doanh nghiệp đáng dùng khi bạn cần kiểm soát API contract, form schema, CMS payload và cấu hình môi trường. Bài này giúp

React Server Components performance: khi nào nên dùng?

React Server Components performance không phải phép màu. Bài này giúp bạn biết khi nào RSC giảm JavaScript thật, khi nào làm kiến trúc phức tạp

Git commit nhầm file: bỏ file khỏi commit an toàn

Bài viết hướng dẫn xử lý git commit nhầm file theo từng tình huống: chưa commit, đã commit chưa push, đã push lên remote, hoặc lỡ

Git reflog: khôi phục commit đã mất an toàn

Bài viết hướng dẫn dùng git reflog để khôi phục commit đã mất sau reset, rebase, amend hoặc xóa nhánh. Bạn sẽ biết cách đọc reflog,

Git pull bị conflict: cách sửa không mất code

Bài viết hướng dẫn cách xử lý git pull bị conflict theo từng bước: kiểm tra trạng thái, sửa file xung đột, test lại và hoàn

Next.js production performance: chọn SSR, SSG, ISR hay Edge

Bài viết giúp developer và tech lead chọn cách render phù hợp để tối ưu Next.js production performance mà không làm kiến trúc phức tạp quá

Nâng cấp Laravel 13: Checklist 10 bước cần kiểm tra

Hướng dẫn nâng cấp Laravel 13 chi tiết với checklist 10 bước. Từ kiểm tra PHP 8.3, cập nhật dependencies, đến xử lý lỗi thường gặp

Hardening Laravel production: Checklist bảo mật cần làm

Checklist hardening Laravel production toàn diện. Từ cấu hình server, database, SSL đến security headers, rate limiting và monitoring.

Authentication và authorization trong Laravel: Cách phân biệt

Hướng dẫn chi tiết cách xây dựng hệ thống Authentication (xác thực) và Authorization (phân quyền) trong Laravel với Breeze, Fortify, Sanctum, Policies và Gates.

Bảo mật Laravel: 10 lỗi phổ biến và cách phòng tránh

Hướng dẫn 10 lỗi bảo mật phổ biến nhất trong Laravel và cách phòng tránh hiệu quả. Từ XSS, SQL injection đến authentication vulnerabilities.