Get in touch
or send us a question?
CONTACT

 Laravel 11 có gì mới

overview

  • Đầu tiên thứ đập vào mắt của chúng ta là laravel có một khung giao diện vô cùng mới và cũng được tinh gọn hơn về mặt source code cũng như về cấu trúc dữ liệu trong dự án và tích hợp thêm một số công nghệ mới giúp tăng hiệu suất cho dự án của bạn. Không dài dòng liên thiên nữa bây giờ thì hãy cùng mình tìm hiểu nhé!

Cấu trúc thư mục

  • Dưới đây là cấu trúc thư mục của laravel 11 sau khi đã được tinh gọn
app/
├── Http/
│   └── Controllers/
│       └── Controller.php
├── Models/
│   └── User.php
└── Providers/
    └── AppServiceProvider.php
bootstrap/
├── app.php
└── providers.php
config
  • Từ cấu trúc thư mục mới có thể thấy các thành phần như app/Consoleapp/Exceptionsapp/Http/Middlewareroutes/channel.phproutes/console.phproutes/api.php đã được loại bỏ trong project base của bạn khi khởi tạo laravel và được đưa vào vendor
  • Middlewares và Exceptions cũng được di chuyển vào trong bootstrap/app.php
  • Và đây là cấu hình của file bootstrap/app.php trong phiên bản mới:
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;
 
return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        commands: __DIR__.'/../routes/console.php',
        health: '/up',
    )
    ->withMiddleware(function (Middleware $middleware) { 
        //
    })
    ->withExceptions(function (Exceptions $exceptions) {
        //
    })->create(); 
  • Vì trong mục tính năng mới này có rất nhiều mục thay đổi nên mình sẽ để link thay đổi source code của version laravel 11 các bạn có thể xem thêm tại: https://github.com/laravel/framework/pull/47309

Cấu hình dự án

  • Tới phiên bản laravel 11 thì một số phần cấu hình trong thư mục config đã bị lược bỏ như:
  • config/broadcasting.php
  • config/cors.php
  • config/hashing.php
  • config/sanctum.php
  • config/view.php

API and Broadcasting

  • routes/api.php đã bị loại bỏ ở version này và nếu muốn sử dụng bạn cần cài thủ công bằng lệnh php artisan install:api khi này routes/api.php sẽ được tạo và đăng kí tại bootstrap/app.php và bạn cần thêm Laravel\Sanctum\HasApiTokens vào trong User
  • Xin giới thiệu sơ qua về Broadcasting cho những bạn nào còn chưa biết hoặc chưa có dịp sử dụng thì Broadcasting là một cơ chế cho phép bạn truyền dữ liệu từ máy chủ đến các ứng dụng web hoặc ứng dụng di động thông qua WebSocket được dùng để xây dựng các tính năng như chat, thông báo, cập nhập dữ liệu ngay lập tức … và với version laravel 11 thì các bạn phải install thủ công bằng lệnh php artisan install:broadcast

Một số lệnh mới

  • php artisan make:enum
  • php artisan make:class
  • php artisan make:interface
  • Thay vì sử dụng property $casts thì nay sẽ chuyển thành casts() như ví dụ và các bạn có thể tham khảo thêm tại https://github.com/laravel/framework/pull/47237
class User extends Authenticatable
{
    // ...
 
    protected function casts(): array
    {
        return [
            'email_verified_at' => 'datetime',
            'password' => 'hashed',
        ];
    }
}
  • Ngoài ra các bạn cũng có thể sử dụng dạng
protected function casts(): array
{
    return [
        'bookOptions' => [AsCollection::class, OptionCollection::class],
    ];
}
  • Thêm mới function once() chỉ cho phép gọi 1 lần các bạn có thể hình dung theo ví dụ dưới nhé
class User extends Model
{
    public function stats(): array
    {
        return once(function () {
            // Expensive operations to generate user stats, multiple db queries, etc...
 
            return $stats;
        });
    }
}
$userA->stats();
$userA->stats(); // cached result from previous line...
 
$userB->stats(); // Not using $userA cached results, because $userB !== $userA
$userB->stats(); 
  • Và đây là file bootstrap/app.php
  • Câu lệnh debug mới dump()
use Illuminate\Support\Traits\Dumpable;

class User extends Model
{
    use Dumpable;
}
...

$model = User::find(1);
$model->dump();

...
$model->dd();
  • Laravel 11 kèm với Route đã đăng ký mới /up nhằm kiểm tra tình trạng cũng như thời gian phản hồi.
return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        commands: __DIR__.'/../routes/console.php',
        channels: __DIR__.'/../routes/channels.php',
        health: '/up', 
    )
    ->withMiddleware(function (Middleware $middleware) {
        //
    })
    ->withExceptions(function (Exceptions $exceptions) {
        //
    })->create();
  • Thiết lập sự kiện kiểm tra với DiagnosingHealth trong file src / Illuminate / Foundation / Configuration / ApplicationBuilder.php
use Illuminate\Foundation\Events\DiagnosingHealth;
use Illuminate\Support\Facades\View;
 
class ApplicationBuilder
{
    // ...
 
    protected function buildRoutingCallback(?string $web,
        ?string $api,
        ?string $pages,
        ?string $health,
        string $apiPrefix,
        ?callable $then)
    {
        return function () use ($web, $api, $pages, $health, $apiPrefix, $then) {
            if (is_string($api) && realpath($api) !== false) {
                Route::middleware('api')->prefix($apiPrefix)->group($api);
            }
 
            if (is_string($health)) { 
                Route::middleware('web')->get($health, function () {
                    Event::dispatch(new DiagnosingHealth);
 
                    return View::file(__DIR__.'/../resources/health-up.blade.php');
                });
            } 
 
            if (is_string($web) && realpath($web) !== false) {
                Route::middleware('web')->group($web);
            }
 
            if (is_string($pages) &&
                realpath($pages) !== false &&
                class_exists(Folio::class)) {
                Folio::route($pages, middleware: $this->pageMiddleware);
            }
 
            if (is_callable($then)) {
                $then($this->app);
            }
        };
    }
 
    // ...
}

Giới hạn tốc độ

RateLimiter::for('invoices', function (Request $request) {
    return Limit::perSecond(1);
});