Chào mọi người, series học Laravel mình viết từ phiên bản 5.3, sau đó là series Laravel 8. Đến nay Laravel đã thay đổi khá nhiều, nhiều thứ trong hai series đó đã cũ. Vì vậy mình sẽ viết một series mới từ đầu trên nền Laravel 13.
Trong series này, chúng ta sẽ vừa học vừa xây dựng một ứng dụng quản lý công việc tên là TaskFlow (project, task, tag, người dùng, API...). Mỗi bài sẽ thêm một phần vào ứng dụng này.
Bài đầu tiên mình sẽ điểm qua những tính năng mới chính trong Laravel 13 để mọi người nắm được tổng quan trước. Mỗi tính năng sẽ được nói chi tiết ở bài tương ứng trong series (mình có ghi số bài ở từng mục).
1. Laravel 13 và chính sách hỗ trợ.
Laravel 13 được phát hành ngày 17/03/2026, đúng lịch mỗi năm một bản major của Laravel. Phiên bản này yêu cầu tối thiểu PHP 8.3 và hỗ trợ PHP 8.3 đến 8.5. Series này mình sẽ dùng PHP 8.4.
Mỗi bản major của Laravel được sửa lỗi (bug fix) trong 18 tháng và vá bảo mật (security fix) trong 2 năm. Cụ thể với hai phiên bản gần nhất:
| Phiên bản | PHP | Phát hành | Sửa lỗi đến | Vá bảo mật đến |
|---|---|---|---|---|
| Laravel 12 | 8.2 - 8.5 | 24/02/2025 | 13/08/2026 | 24/02/2027 |
| Laravel 13 | 8.3 - 8.5 | 17/03/2026 | Quý 3/2027 | 17/03/2028 |
Như vậy, tính đến thời điểm viết bài này Laravel 12 chỉ còn nhận bản vá bảo mật, nên dự án mới các bạn nên bắt đầu luôn với Laravel 13.
Điểm đáng chú ý là Laravel 13 có rất ít breaking change. Đội ngũ Laravel tập trung giữ cho code cũ chạy được, nên phần lớn ứng dụng Laravel 12 có thể nâng cấp mà không phải sửa nhiều code (mình sẽ nói ở mục 9).
2. Laravel AI SDK.
Đây là tính năng nổi bật nhất của Laravel 13. Laravel AI SDK (package laravel/ai) là package chính chủ của Laravel, cung cấp một API thống nhất để làm việc với các nhà cung cấp AI như OpenAI, Anthropic, Gemini... Đổi nhà cung cấp thì code của bạn gần như không phải sửa.
Cài đặt package qua Composer:
composer require laravel/ai
Thành phần chính của AI SDK là agent: một class chứa hướng dẫn (instructions), tool và ngữ cảnh hội thoại cho mô hình AI. Các bạn tạo agent bằng lệnh php artisan make:agent.
VD: Một agent tóm tắt danh sách công việc cho TaskFlow.
- app/Ai/Agents/TaskSummarizer.php
<?php
namespace App\Ai\Agents;
use Laravel\Ai\Contracts\Agent;
use Laravel\Ai\Promptable;
use Stringable;
class TaskSummarizer implements Agent
{
use Promptable;
public function instructions(): Stringable|string
{
return 'Bạn là trợ lý quản lý dự án. Hãy tóm tắt danh sách công việc ngắn gọn bằng tiếng Việt.';
}
}
Lúc này chỉ cần một dòng là chúng ta đã gửi được prompt cho agent:
use App\Ai\Agents\TaskSummarizer;
$response = TaskSummarizer::make()->prompt('Tóm tắt các task còn lại của project TaskFlow...');
return (string) $response;
Ngoài văn bản, AI SDK còn tạo được hình ảnh, âm thanh và embedding (vector biểu diễn ý nghĩa của một đoạn văn bản, dùng cho tìm kiếm theo ngữ nghĩa ở mục 8):
use Illuminate\Support\Str;
use Laravel\Ai\Audio;
use Laravel\Ai\Image;
// Tạo ảnh từ mô tả
$image = Image::of('Một chiếc bàn làm việc gọn gàng với laptop')->generate();
// Chuyển văn bản thành giọng nói
$audio = Audio::of('Bạn có 3 công việc sắp đến hạn.')->generate();
// Tạo embedding từ chuỗi
$embeddings = Str::of('Viết báo cáo tuần cho khách hàng')->toEmbeddings();
Lưu ý: Để chạy thật các ví dụ trên, các bạn cần khai báo API key của nhà cung cấp AI (VD: OPENAI_API_KEY) trong file .env. Cách cấu hình và dùng AI SDK cho TaskFlow mình sẽ hướng dẫn ở Bài 31.
3. JSON:API resource.
Laravel 13 có sẵn class JsonApiResource giúp trả về response theo chuẩn JSON:API. Class này tự xử lý cấu trúc resource object, quan hệ (relationship), include, sparse fieldset và header Content-Type: application/vnd.api+json.
Để tạo một JSON:API resource, các bạn thêm option --json-api vào lệnh make:resource:
php artisan make:resource ProjectResource --json-api
VD: Khai báo các thuộc tính trả về của ProjectResource.
- app/Http/Resources/ProjectResource.php
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\JsonApi\JsonApiResource;
class ProjectResource extends JsonApiResource
{
/**
* Các thuộc tính trả về trong "attributes".
*/
public $attributes = [
'name',
'description',
];
}
- routes/web.php
use App\Http\Resources\ProjectResource;
use App\Models\Project;
Route::get('/api/projects/{project}', function (Project $project) {
return new ProjectResource($project);
});
Kết quả khi truy cập /api/projects/1:
{
"data": {
"id": "1",
"type": "projects",
"attributes": {
"name": "TaskFlow",
"description": "Ứng dụng quản lý công việc"
}
}
}
API resource và JSON:API sẽ được nói kỹ ở Bài 24.
4. Middleware PreventRequestForgery.
Middleware chống CSRF của Laravel được đổi tên từ VerifyCsrfToken thành PreventRequestForgery và được bổ sung thêm bước kiểm tra nguồn gốc request (origin).
Cụ thể, middleware này kiểm tra theo hai lớp:
- Đầu tiên nó đọc header
Sec-Fetch-Sitemà trình duyệt hiện đại tự gửi kèm. Nếu header cho biết request đến từ cùng origin (same-origin) thì request được cho qua luôn. - Nếu bước trên không đạt (trình duyệt cũ không gửi header, kết nối không an toàn...), middleware quay lại kiểm tra CSRF token như trước, nên
@csrftrong form vẫn hoạt động bình thường.
Nếu muốn chỉ dùng kiểm tra origin và bỏ hẳn bước kiểm tra token, các bạn cấu hình trong bootstrap/app.php:
->withMiddleware(function (Middleware $middleware): void {
$middleware->preventRequestForgery(originOnly: true);
})
Ở chế độ này, request không qua được bước kiểm tra origin sẽ nhận response 403 thay vì 419 như khi sai CSRF token. Middleware nói chung mình sẽ nói ở Bài 9.
5. Queue routing.
Trước đây muốn một job luôn chạy trên một connection hay queue nhất định, chúng ta phải khai báo trong từng job hoặc mỗi lần dispatch. Laravel 13 thêm phương thức Queue::route() để khai báo các quy tắc này ở một chỗ, thường là trong method boot của service provider.
VD: Job SendTaskReminder luôn được đưa vào queue reminders của connection database.
- app/Providers/AppServiceProvider.php
use App\Jobs\SendTaskReminder;
use Illuminate\Support\Facades\Queue;
public function boot(): void
{
Queue::route(SendTaskReminder::class, connection: 'database', queue: 'reminders');
}
Lúc này mỗi lần gọi SendTaskReminder::dispatch(), job sẽ được ghi vào queue reminders mà không cần gọi thêm ->onQueue(). Ngoài tên class, các bạn cũng có thể truyền vào một interface, trait hoặc class cha để áp dụng cho cả nhóm job. Queue và job sẽ được nói chi tiết ở Bài 28.
6. Mở rộng PHP attribute.
Từ PHP 8 chúng ta đã có attribute. Laravel 13 bổ sung thêm nhiều attribute để khai báo cấu hình ngay trên class và method, thay vì viết thêm property hay method riêng.
Attribute cho controller.
Với controller, các bạn có thể dùng #[Middleware] để gắn middleware và #[Authorize] để kiểm tra quyền bằng policy.
VD: Bắt buộc đăng nhập với mọi action của ProjectController và kiểm tra quyền update trước khi sửa project.
- app/Http/Controllers/ProjectController.php
<?php
namespace App\Http\Controllers;
use App\Models\Project;
use Illuminate\Routing\Attributes\Controllers\Authorize;
use Illuminate\Routing\Attributes\Controllers\Middleware;
#[Middleware('auth')]
class ProjectController
{
#[Authorize('update', 'project')]
public function update(Project $project)
{
// Chỉ chạy khi người dùng đã đăng nhập và có quyền update project này
}
}
Với route Route::put('/projects/{project}', [ProjectController::class, 'update']) trong routes/web.php, khi chạy php artisan route:list -v các bạn sẽ thấy route PUT projects/{project} đã có middleware auth và Illuminate\Auth\Middleware\Authorize:update,project (chính là middleware can). Middleware sẽ có ở Bài 9, còn policy và #[Authorize] ở Bài 22.
Attribute cho job.
Với job, Laravel 13 có #[Tries] (số lần thử tối đa), #[Backoff] (số giây chờ giữa các lần thử lại), #[Timeout] (thời gian chạy tối đa) và #[FailOnTimeout] (đánh dấu job thất bại luôn khi quá thời gian, không thử lại).
- app/Jobs/SendTaskReminder.php
<?php
namespace App\Jobs;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;
use Illuminate\Queue\Attributes\Backoff;
use Illuminate\Queue\Attributes\FailOnTimeout;
use Illuminate\Queue\Attributes\Timeout;
use Illuminate\Queue\Attributes\Tries;
#[Tries(3)]
#[Backoff([10, 30, 60])]
#[Timeout(120)]
#[FailOnTimeout]
class SendTaskReminder implements ShouldQueue
{
use Queueable;
public function handle(): void
{
// Gửi email nhắc việc...
}
}
Ngoài controller và job, Laravel 13 còn thêm attribute cho Eloquent, event, notification, validation, testing... Chúng ta sẽ gặp dần khi học đến từng phần đó, VD attribute cho job ở Bài 28.
7. Cache::touch().
Phương thức mới Cache::touch() cho phép gia hạn thời gian sống (TTL) của một item trong cache mà không cần lấy giá trị ra rồi lưu lại. Phương thức trả về true nếu item tồn tại và được gia hạn, false nếu item không có trong cache.
use Illuminate\Support\Facades\Cache;
Cache::put('project_stats', ['todo' => 5], 60);
var_dump(Cache::touch('project_stats', 3600)); // bool(true)
var_dump(Cache::touch('not_found', 3600)); // bool(false)
// Có thể truyền vào thời điểm hết hạn cụ thể
Cache::touch('project_stats', now()->addHours(2));
Cache sẽ được nói kỹ ở Bài 29.
8. Tìm kiếm theo ngữ nghĩa (vector search).
Kết hợp với embedding của AI SDK, query builder của Laravel 13 có thêm phương thức whereVectorSimilarTo() để tìm các bản ghi có ý nghĩa gần giống với một đoạn văn bản, thay vì phải khớp từ khóa như LIKE.
$tasks = DB::table('tasks')
->whereVectorSimilarTo('embedding', 'Chuẩn bị tài liệu cho buổi họp')
->limit(10)
->get();
Trong đó:
embeddinglà cột kiểu vector lưu embedding của từng task.- Tham số thứ hai là chuỗi cần tìm. Khi truyền vào một chuỗi, Laravel sẽ tự dùng AI SDK để tạo embedding cho nó. Các bạn cũng có thể truyền vào một mảng số (embedding đã có sẵn).
Kết quả được sắp xếp theo độ giống nhau giảm dần.
Chú ý: Tính năng này cần database hỗ trợ vector: PostgreSQL với extension pgvector (theo tài liệu query builder thì MariaDB 11.7 trở lên cũng được hỗ trợ). MySQL và SQLite chưa dùng được.
9. Nâng cấp từ Laravel 12.
Theo hướng dẫn chính thức, thời gian nâng cấp ước tính chỉ khoảng 10 phút. Việc đầu tiên là cập nhật các package trong composer.json rồi chạy composer update:
laravel/frameworklên^13.0,laravel/tinkerlên^3.0.phpunit/phpunitlên^12.0(hoặcpestphp/pestlên^4.0nếu dùng Pest).laravel/boostlên^2.0nếu có dùng.
Một vài thay đổi các bạn nên kiểm tra thêm:
- Nếu code có tham chiếu trực tiếp đến
VerifyCsrfToken(VD:->withoutMiddleware([VerifyCsrfToken::class])trong test) thì nên đổi sangPreventRequestForgery. Tên cũ vẫn chạy nhưng đã bị đánh dấu deprecated. - File
config/cache.phpmới có thêm optionserializable_classesmặc định làfalse. Nếu ứng dụng lưu object PHP vào cache, các bạn cần liệt kê các class đó vào option này. - Prefix mặc định của cache, Redis và tên cookie session đổi sang dạng gạch ngang (
-cache-,-session). Thay đổi này chỉ ảnh hưởng khi file config của ứng dụng (config/cache.php,config/database.php,config/session.php) không khai báo các giá trị này mà dùng giá trị dự phòng của framework; phần lớn ứng dụng đã khai báo sẵn nên không bị ảnh hưởng. Nếu ứng dụng của các bạn thuộc trường hợp đó và muốn giữ như cũ, các bạn khai báoCACHE_PREFIX,REDIS_PREFIXvàSESSION_COOKIEtrong.env.
Danh sách đầy đủ các thay đổi các bạn có thể xem tại đây.
10. Lời kết.
Trên đây là những tính năng mới chính trong Laravel 13: AI SDK, JSON:API resource, PreventRequestForgery, queue routing, PHP attribute, Cache::touch() và vector search. Danh sách đầy đủ các bạn có thể xem trong release notes chính thức. Bài sau mình sẽ hướng dẫn mọi người cài đặt Laravel 13 và khởi tạo project TaskFlow.
Đăng ký nhận tin.
Chúng tôi chỉ gửi tối đa 2 lần trên 1 tháng. Tuyên bố không spam mail!





0 Comments