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

Quy trình vibe coding 7 bước: từ ý tưởng đến prototype

Quy trình vibe coding hiệu quả bắt đầu từ giả thuyết kinh doanh, không phải prompt dài. Bài viết hướng dẫn 7 bước từ brief, dữ

Vibe coding cho doanh nghiệp: việc nào nên làm bằng AI?

Vibe coding cho doanh nghiệp hữu ích khi cần thử prototype, dashboard hoặc automation nhỏ. Bài viết giúp bạn phân loại use case theo mức rủi

AI viết code nhanh hơn review: kiểm soát thế nào?

Khi AI viết code nhanh hơn khả năng review của team, doanh nghiệp cần đổi cách kiểm soát chất lượng. Bài viết đưa ra framework thực

Git detached HEAD là gì? Cách thoát an toàn

Bài viết này giải thích detached HEAD trong Git, cách nhận biết trạng thái này và các bước thoát ra an toàn mà không mất code.

Rủi ro vibe coding: 9 lỗi khiến prototype khó vận hành

Bài viết này chỉ ra 9 rủi ro phổ biến khi vibe coding và cách kiểm soát để prototype không biến thành gánh nặng vận hành.

Vibe coding là gì? Cách thử ý tưởng phần mềm bằng AI

Vibe coding giúp chủ doanh nghiệp biến ý tưởng phần mềm thành prototype nhanh hơn bằng AI. Bài viết này chỉ ra khi nào nên thử,

GitHub Actions CI/CD: quy trình deploy website an toàn

Hướng dẫn xây pipeline GitHub Actions CI/CD cho website: build, test, cache dependency, đóng artifact, deploy staging/production và quản lý secret an toàn.

.gitignore không hoạt động: nguyên nhân và cách sửa

Bài viết giúp bạn kiểm tra vì sao .gitignore không hoạt động, sửa lỗi file đã tracked và dùng git check-ignore để debug pattern.

Git push bị rejected: cách sửa non-fast-forward

Bài viết giải thích vì sao git push bị rejected, cách đọc lỗi non-fast-forward và quy trình xử lý an toàn trước khi push lại.

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