Hướng dẫn php 8 vs 9 - php 8 so với 9

Laravel v9 là phiên bản LTS tiếp theo của Laravel và ra mắt vào tháng 2 năm 2022. Trong bài viết này, mình xin giới thiệu một vài tính năng mới trong Laravel trong Laravel 9.0

PHP Version

Laravel 9 yêu cầu sử dụng phiên bản tối thiểu là PHP 8 và Symfony 6.0

Route:list

Lệnh

public function getNameAttribute($value)
{
    return strtoupper($value);
}
 
public function setNameAttribute($value)
{
    $this->attributes['name'] = $value;
}
4 đã được đưa vào Laravel từ lâu, nhưng có một số vấn đề đôi khi nảy sinh khi bạn xác định một route lớn và phức tạp, nó có thể trở nên khó kiểm soát. Nhờ có Nuno Maduro nên
public function getNameAttribute($value)
{
    return strtoupper($value);
}
 
public function setNameAttribute($value)
{
    $this->attributes['name'] = $value;
}
5 đã trở nên dễ dàng và đẹp mắt hơn.
Hướng dẫn php 8 vs 9 - php 8 so với 9

artisan test --coverage

Câu lệnh

public function getNameAttribute($value)
{
    return strtoupper($value);
}
 
public function setNameAttribute($value)
{
    $this->attributes['name'] = $value;
}
6 sẽ hiển thị phạm vi kiểm tra trực tiếp trên thiết bị đầu cuối. Nó cũng bao gồm một
public function getNameAttribute($value)
{
    return strtoupper($value);
}
 
public function setNameAttribute($value)
{
    $this->attributes['name'] = $value;
}
7 tùy chọn mà bạn có thể sử dụng để chỉ ra mức thực thi ngưỡng tối thiểu cho phạm vi kiểm tra.
Hướng dẫn php 8 vs 9 - php 8 so với 9

Anonymous trong Migrations

Trước đây, mỗi khi bạn chạy lệnh

public function getNameAttribute($value)
{
    return strtoupper($value);
}
 
public function setNameAttribute($value)
{
    $this->attributes['name'] = $value;
}
8 thì sẽ tạo ra một class có tên dựa theo tên mà bạn đặt, điều này dễ xảy ra xung đột khi vô tình bạn đặt trùng tên với tên migration đã tạo trước đó. Ở phiên bản 8.x Laravel đã ra mắt với một tính năng mới được gọi là Anonymous Stub giúp ngăn chặn xung đột tên của class migration. Kể từ bây giờ, khi bạn chạy make:migration thì nó sẽ return về là một class Anonymous thay vì một class có tên.Anonymous Stub giúp ngăn chặn xung đột tên của class migration. Kể từ bây giờ, khi bạn chạy make:migration thì nó sẽ return về là một class Anonymous thay vì một class có tên.

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
 
return new class extends Migration {
 
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('people', function (Blueprint $table) {
            $table->string('first_name')->nullable();
        });
    }
};

Query Builder Interface

Ở phiên bản trước đây, khi chúng ta sử dụng

public function getNameAttribute($value)
{
    return strtoupper($value);
}
 
public function setNameAttribute($value)
{
    $this->attributes['name'] = $value;
}
9 ở trong các câu lệnh
use Illuminate\Database\Eloquent\Casts\Attribute;
 
public function name(): Attribute
{
    return new Attribute(
        get: fn ($value) => strtoupper($value),
        set: fn ($value) => $value,
    );
}
0 nên khó khăn khi nó là
use Illuminate\Database\Eloquent\Casts\Attribute;
 
public function name(): Attribute
{
    return new Attribute(
        get: fn ($value) => strtoupper($value),
        set: fn ($value) => $value,
    );
}
1 hay đôi khi là
use Illuminate\Database\Eloquent\Casts\Attribute;
 
public function name(): Attribute
{
    return new Attribute(
        get: fn ($value) => strtoupper($value),
        set: fn ($value) => $value,
    );
}
2. Bạn có thể tham khảo thêm tại https://github.com/laravel/framework/pull/37956:

return Model::query()
	->whereNotExists(function($query) {
		// $query is a Query\Builder
	})
	->whereHas('relation', function($query) {
		// $query is an Eloquent\Builder
	})
	->with('relation', function($query) {
		// $query is an Eloquent\Relation
	});

Ở phiên bản Laravel 9 tính năng này bổ sung một

use Illuminate\Database\Eloquent\Casts\Attribute;
 
public function name(): Attribute
{
    return new Attribute(
        get: fn ($value) => strtoupper($value),
        set: fn ($value) => $value,
    );
}
3 mới và một
use Illuminate\Database\Eloquent\Casts\Attribute;
 
public function name(): Attribute
{
    return new Attribute(
        get: fn ($value) => strtoupper($value),
        set: fn ($value) => $value,
    );
}
4 đặc điểm thực hiện thay cho
use Illuminate\Database\Eloquent\Casts\Attribute;
 
public function name(): Attribute
{
    return new Attribute(
        get: fn ($value) => strtoupper($value),
        set: fn ($value) => $value,
    );
}
5 hiện tại. Giúp cho IDE hay VS Code đồng nhất.

PHP 8 String Functions

Vì mức tối thiểu là PHP 8, nên một số function trước đây bị bỏ đi nên Tom Schlick đã gửi PR để chuyển sang sử dụng

use Illuminate\Database\Eloquent\Casts\Attribute;
 
public function name(): Attribute
{
    return new Attribute(
        get: fn ($value) => strtoupper($value),
        set: fn ($value) => $value,
    );
}
6 và
use Illuminate\Database\Eloquent\Casts\Attribute;
 
public function name(): Attribute
{
    return new Attribute(
        get: fn ($value) => strtoupper($value),
        set: fn ($value) => $value,
    );
}
7 các
use Illuminate\Database\Eloquent\Casts\Attribute;
 
public function name(): Attribute
{
    return new Attribute(
        get: fn ($value) => strtoupper($value),
        set: fn ($value) => $value,
    );
}
8 chức năng nội bộ trong lớp
use Illuminate\Database\Eloquent\Casts\Attribute;
 
public function name(): Attribute
{
    return new Attribute(
        get: fn ($value) => strtoupper($value),
        set: fn ($value) => $value,
    );
}
9.Tom Schlick đã gửi PR để chuyển sang sử dụng
use Illuminate\Database\Eloquent\Casts\Attribute;
 
public function name(): Attribute
{
    return new Attribute(
        get: fn ($value) => strtoupper($value),
        set: fn ($value) => $value,
    );
}
6 và
use Illuminate\Database\Eloquent\Casts\Attribute;
 
public function name(): Attribute
{
    return new Attribute(
        get: fn ($value) => strtoupper($value),
        set: fn ($value) => $value,
    );
}
7 các
use Illuminate\Database\Eloquent\Casts\Attribute;
 
public function name(): Attribute
{
    return new Attribute(
        get: fn ($value) => strtoupper($value),
        set: fn ($value) => $value,
    );
}
8 chức năng nội bộ trong lớp
use Illuminate\Database\Eloquent\Casts\Attribute;
 
public function name(): Attribute
{
    return new Attribute(
        get: fn ($value) => strtoupper($value),
        set: fn ($value) => $value,
    );
}
9.

SwiftMailer to Symfony Mailer

Các bản phát hành trước của Laravel đã sử dụng thư viện Swift Mailer để tạo object mail và gửi email. Tuy nhiên, thư viện đó không còn được duy trì và đã được thay bởi Symfony Mailer. Vui lòng xem lại hướng dẫn nâng cấp để tìm hiểu thêm về cách đảm bảo ứng dụng của bạn tương thích với Symfony Mailer.

Flysystem 3.x

Laravel 9.x nâng cấp phụ thuộc vào hệ thống Flysystem để lên Flysystem 3.x. Flysystem cung cấp cho tất cả các giao tiếp hệ thống tệp được cung cấp bởi

use App\Support\Address;
use Illuminate\Database\Eloquent\Casts\Attribute;
 
public function address(): Attribute
{
    return new Attribute(
        get: fn ($value, $attributes) => new Address(
            $attributes['address_line_one'],
            $attributes['address_line_two'],
        ),
        set: fn (Address $value) => [
            'address_line_one' => $value->lineOne,
            'address_line_two' => $value->lineTwo,
        ],
    );
}
0.

Improved Eloquent Accessors / Mutators

Accessors và Mutators là những phương thức, khi chúng ta đặt nó thì các bạn có thể gọi properties từ một model, khi properties không có trong model thì nó sẽ tìm Accessors bằng phương thức GET, ngược lại với Accessors, Mutators là phương thức SET. Laravel 9.x cung cấp một cách mới để xác định các trình truy cập và trình đột biến Eloquent.Mutators là những phương thức, khi chúng ta đặt nó thì các bạn có thể gọi properties từ một model, khi properties không có trong model thì nó sẽ tìm Accessors bằng phương thức GET, ngược lại với Accessors, Mutators là phương thức SET. Laravel 9.x cung cấp một cách mới để xác định các trình truy cập và trình đột biến Eloquent.

public function getNameAttribute($value)
{
    return strtoupper($value);
}
 
public function setNameAttribute($value)
{
    $this->attributes['name'] = $value;
}

Ở trên gồm 2 function là

use App\Support\Address;
use Illuminate\Database\Eloquent\Casts\Attribute;
 
public function address(): Attribute
{
    return new Attribute(
        get: fn ($value, $attributes) => new Address(
            $attributes['address_line_one'],
            $attributes['address_line_two'],
        ),
        set: fn (Address $value) => [
            'address_line_one' => $value->lineOne,
            'address_line_two' => $value->lineTwo,
        ],
    );
}
1 trả về
use App\Support\Address;
use Illuminate\Database\Eloquent\Casts\Attribute;
 
public function address(): Attribute
{
    return new Attribute(
        get: fn ($value, $attributes) => new Address(
            $attributes['address_line_one'],
            $attributes['address_line_two'],
        ),
        set: fn (Address $value) => [
            'address_line_one' => $value->lineOne,
            'address_line_two' => $value->lineTwo,
        ],
    );
}
2 in HOA và
use App\Support\Address;
use Illuminate\Database\Eloquent\Casts\Attribute;
 
public function address(): Attribute
{
    return new Attribute(
        get: fn ($value, $attributes) => new Address(
            $attributes['address_line_one'],
            $attributes['address_line_two'],
        ),
        set: fn (Address $value) => [
            'address_line_one' => $value->lineOne,
            'address_line_two' => $value->lineTwo,
        ],
    );
}
3 trả về
use App\Support\Address;
use Illuminate\Database\Eloquent\Casts\Attribute;
 
public function address(): Attribute
{
    return new Attribute(
        get: fn ($value, $attributes) => new Address(
            $attributes['address_line_one'],
            $attributes['address_line_two'],
        ),
        set: fn (Address $value) => [
            'address_line_one' => $value->lineOne,
            'address_line_two' => $value->lineTwo,
        ],
    );
}
4 là
use App\Support\Address;
use Illuminate\Database\Eloquent\Casts\Attribute;
 
public function address(): Attribute
{
    return new Attribute(
        get: fn ($value, $attributes) => new Address(
            $attributes['address_line_one'],
            $attributes['address_line_two'],
        ),
        set: fn (Address $value) => [
            'address_line_one' => $value->lineOne,
            'address_line_two' => $value->lineTwo,
        ],
    );
}
2 Tuy nhiên, trong Laravel 9.x, bạn có thể xác định bằng một phương thức duy nhất và trả về
use App\Support\Address;
use Illuminate\Database\Eloquent\Casts\Attribute;
 
public function address(): Attribute
{
    return new Attribute(
        get: fn ($value, $attributes) => new Address(
            $attributes['address_line_one'],
            $attributes['address_line_two'],
        ),
        set: fn (Address $value) => [
            'address_line_one' => $value->lineOne,
            'address_line_two' => $value->lineTwo,
        ],
    );
}
6:

use Illuminate\Database\Eloquent\Casts\Attribute;
 
public function name(): Attribute
{
    return new Attribute(
        get: fn ($value) => strtoupper($value),
        set: fn ($value) => $value,
    );
}

Ngoài ra, cách tiếp cận mới này để xác định trình truy cập sẽ lưu vào bộ nhớ cache các giá trị đối tượng được trả về bởi thuộc tính, giống như các lớp truyền tùy chỉnh:

use App\Support\Address;
use Illuminate\Database\Eloquent\Casts\Attribute;
 
public function address(): Attribute
{
    return new Attribute(
        get: fn ($value, $attributes) => new Address(
            $attributes['address_line_one'],
            $attributes['address_line_two'],
        ),
        set: fn (Address $value) => [
            'address_line_one' => $value->lineOne,
            'address_line_two' => $value->lineTwo,
        ],
    );
}

Implicit Route Bindings With Enums

PHP 8.1 giới thiệu hỗ trợ cho Enums. Laravel 9.x giới thiệu khả năng gõ-gợi ý một Enum trên định nghĩa tuyến của bạn và Laravel sẽ chỉ gọi tuyến nếu đoạn tuyến đó là một giá trị Enum hợp lệ trong URI. Nếu không, phản hồi HTTP 404 sẽ được trả về tự động. Ví dụ:

enum Category: string
{
    case Fruits = 'fruits';
    case People = 'people';
}

Bạn có thể xác định một tuyến sẽ chỉ được gọi nếu

use App\Support\Address;
use Illuminate\Database\Eloquent\Casts\Attribute;
 
public function address(): Attribute
{
    return new Attribute(
        get: fn ($value, $attributes) => new Address(
            $attributes['address_line_one'],
            $attributes['address_line_two'],
        ),
        set: fn (Address $value) => [
            'address_line_one' => $value->lineOne,
            'address_line_two' => $value->lineTwo,
        ],
    );
}
7 đoạn tuyến là
use App\Support\Address;
use Illuminate\Database\Eloquent\Casts\Attribute;
 
public function address(): Attribute
{
    return new Attribute(
        get: fn ($value, $attributes) => new Address(
            $attributes['address_line_one'],
            $attributes['address_line_two'],
        ),
        set: fn (Address $value) => [
            'address_line_one' => $value->lineOne,
            'address_line_two' => $value->lineTwo,
        ],
    );
}
8 hoặc
use App\Support\Address;
use Illuminate\Database\Eloquent\Casts\Attribute;
 
public function address(): Attribute
{
    return new Attribute(
        get: fn ($value, $attributes) => new Address(
            $attributes['address_line_one'],
            $attributes['address_line_two'],
        ),
        set: fn (Address $value) => [
            'address_line_one' => $value->lineOne,
            'address_line_two' => $value->lineTwo,
        ],
    );
}
9. Nếu không, phản hồi HTTP 404 sẽ được trả về:

Route::get('/categories/{category}', function (Category $category) {
    return $category->value;
});

Controller Route Groups

Bây giờ bạn có thể sử dụng phương pháp

enum Category: string
{
    case Fruits = 'fruits';
    case People = 'people';
}
0 để xác định bộ điều khiển chung cho tất cả các
enum Category: string
{
    case Fruits = 'fruits';
    case People = 'people';
}
1 trong nhóm. Sau đó, khi xác định các
enum Category: string
{
    case Fruits = 'fruits';
    case People = 'people';
}
1, bạn chỉ cần cung cấp phương thức
enum Category: string
{
    case Fruits = 'fruits';
    case People = 'people';
}
0 mà chúng gọi:

use App\Http\Controllers\OrderController;
 
Route::controller(OrderController::class)->group(function () {
    Route::get('/orders/{id}', 'show');
    Route::post('/orders', 'store');
});

Enum Eloquent Attribute Casting

Eloquent hiện cho phép bạn truyền các giá trị thuộc tính của mình sang các

enum Category: string
{
    case Fruits = 'fruits';
    case People = 'people';
}
4 PHP. Để thực hiện điều này, bạn có thể chỉ định thuộc tính và enum mà bạn muốn truyền trong
enum Category: string
{
    case Fruits = 'fruits';
    case People = 'people';
}
5 mảng thuộc tính của mô hình:

use App\Enums\ServerStatus;
 
/**
 * The attributes that should be cast.
 *
 * @var array
 */
protected $casts = [
    'status' => ServerStatus::class,
];

Khi bạn đã xác định kiểu truyền trên mô hình của mình, thuộc tính được chỉ định sẽ tự động được truyền đến và đi từ một

enum Category: string
{
    case Fruits = 'fruits';
    case People = 'people';
}
4 khi bạn tương tác với thuộc tính:

if ($server->status == ServerStatus::provisioned) {
    $server->status = ServerStatus::ready;
 
    $server->save();
}

Forced Scoped Bindings

Tính này mới này khá thú vị và hữu ích. Forced Scoping Of Route Bindings tạm hiểu là ràng buộc định tuyến. Ví dụ: hãy xem xét định nghĩa tuyến đường này truy xuất một bài đăng trên blog bằng slug cho một người dùng cụ thểVí dụ: hãy xem xét định nghĩa tuyến đường này truy xuất một bài đăng trên blog bằng slug cho một người dùng cụ thể

return Model::query()
	->whereNotExists(function($query) {
		// $query is a Query\Builder
	})
	->whereHas('relation', function($query) {
		// $query is an Eloquent\Builder
	})
	->with('relation', function($query) {
		// $query is an Eloquent\Relation
	});
0

Với route này thì** $post** và $user sẽ không có sự ràng buộc nào lẫn nhau. Có nghĩa là $post sẽ được lấy từ id ở đường dẫn và gọi query vào Model Post. Nhưng khi sử dụng thêm scopeBindings() như thế này thì $post sẽ được ràng buộc thêm điều kiện user_id bằng với id của $user.$user sẽ không có sự ràng buộc nào lẫn nhau. Có nghĩa là $post sẽ được lấy từ id ở đường dẫn và gọi query vào Model Post. Nhưng khi sử dụng thêm scopeBindings() như thế này thì $post sẽ được ràng buộc thêm điều kiện user_id bằng với id của $user.

return Model::query()
	->whereNotExists(function($query) {
		// $query is a Query\Builder
	})
	->whereHas('relation', function($query) {
		// $query is an Eloquent\Builder
	})
	->with('relation', function($query) {
		// $query is an Eloquent\Relation
	});
1

Hoặc, bạn có thể hướng dẫn toàn bộ nhóm định nghĩa tuyến sử dụng liên kết theo phạm vi:

return Model::query()
	->whereNotExists(function($query) {
		// $query is a Query\Builder
	})
	->whereHas('relation', function($query) {
		// $query is an Eloquent\Builder
	})
	->with('relation', function($query) {
		// $query is an Eloquent\Relation
	});
2

Điều này sẽ rất hữu ích khi bạn làm việc với các dữ liệu quan hệ.

Route Controller Group

Như laravel 8 việc khai báo controller sẽ thực hiện bằng cách:

return Model::query()
	->whereNotExists(function($query) {
		// $query is a Query\Builder
	})
	->whereHas('relation', function($query) {
		// $query is an Eloquent\Builder
	})
	->with('relation', function($query) {
		// $query is an Eloquent\Relation
	});
3

Cái này cũng là một cải tiến rất hữu ích, nếu như trước đây khi viết route mà gặp controller có nhiều phương thức thì chúng ta sẽ phải lặp đi lặp lại code khá là dài dòng. Giờ đây thì chúng ta có thể viết lại nó một cách ngắn gọn và dễ hiểu hơn.

return Model::query()
	->whereNotExists(function($query) {
		// $query is a Query\Builder
	})
	->whereHas('relation', function($query) {
		// $query is an Eloquent\Builder
	})
	->with('relation', function($query) {
		// $query is an Eloquent\Relation
	});
4

Laravel Breeze API & Next.js

Bộ khởi động Laravel Breeze đã nhận được chế độ giàn giáo "API" và triển khai giao diện người dùng Next.js miễn phí . Bộ khởi động này có thể được sử dụng để khởi động các ứng dụng Laravel của bạn đang đóng vai trò là chương trình phụ trợ, API được xác thực Laravel Sanctum cho giao diện người dùng JavaScript.

Laravel Scout Database Engine

Nếu ứng dụng của bạn tương tác với cơ sở dữ liệu có kích thước vừa và nhỏ hoặc có khối lượng công việc nhẹ, giờ đây bạn có thể sử dụng công cụ "cơ sở dữ liệu" của Scout thay vì dịch vụ tìm kiếm chuyên dụng như Algolia hoặc MeiliSerach. Công cụ cơ sở dữ liệu sẽ sử dụng các mệnh đề "nơi thích" và chỉ mục văn bản đầy đủ khi lọc kết quả từ cơ sở dữ liệu hiện có của bạn để xác định kết quả tìm kiếm thích hợp cho truy vấn của bạn.

Full Text Indexes / Where Clauses

Khi sử dụng MySQL hoặc PostgreSQL, phương thức

enum Category: string
{
    case Fruits = 'fruits';
    case People = 'people';
}
7 hiện có thể được thêm vào định nghĩa cột để tạo chỉ mục văn bản đầy đủ:

return Model::query()
	->whereNotExists(function($query) {
		// $query is a Query\Builder
	})
	->whereHas('relation', function($query) {
		// $query is an Eloquent\Builder
	})
	->with('relation', function($query) {
		// $query is an Eloquent\Relation
	});
5

Ngoài ra, các phương thức

enum Category: string
{
    case Fruits = 'fruits';
    case People = 'people';
}
8 và
enum Category: string
{
    case Fruits = 'fruits';
    case People = 'people';
}
9 có thể được sử dụng để thêm văn bản đầy đủ mệnh đề "where" vào truy vấn cho các cột có chỉ mục văn bản đầy đủ. Các phương thức này sẽ được Laravel chuyển thành SQL thích hợp cho hệ thống cơ sở dữ liệu bên dưới. Ví dụ: mệnh đề MATCH AGAINST sẽ được tạo cho các ứng dụng sử dụng MySQL:"where" vào truy vấn cho các cột có chỉ mục văn bản đầy đủ. Các phương thức này sẽ được Laravel chuyển thành SQL thích hợp cho hệ thống cơ sở dữ liệu bên dưới. Ví dụ: mệnh đề MATCH AGAINST sẽ được tạo cho các ứng dụng sử dụng MySQL:

return Model::query()
	->whereNotExists(function($query) {
		// $query is a Query\Builder
	})
	->whereHas('relation', function($query) {
		// $query is an Eloquent\Builder
	})
	->with('relation', function($query) {
		// $query is an Eloquent\Relation
	});
6

Rendering Inline Blade Templates

Tính năng này mình đã tìm kiếm rất lâu rồi, và bây giờ nó đã được tích hợp vào trong bản cập nhật này. Trước đây, thỉnh thoảng mình có một số task cần render một đoạn text thành HTML. Và mình đã phải rất cực khổ chỉ để render một dòng text. Nào là phải khai báo rất nhiều, hoặc là phải tạo ra một file blade tạm chỉ để render nội dung ra. Nhưng giờ đây nó đã được đơn giản hoá bằng một dòng code như sau:

return Model::query()
	->whereNotExists(function($query) {
		// $query is a Query\Builder
	})
	->whereHas('relation', function($query) {
		// $query is an Eloquent\Builder
	})
	->with('relation', function($query) {
		// $query is an Eloquent\Relation
	});
7

Soketi Echo Server

Mặc dù không dành riêng cho Laravel 9.x, nhưng gần đây Laravel đã hỗ trợ tài liệu về Soketi, một máy chủ Web Socket tương thích với Laravel Echo được viết cho Node.js. Soketi cung cấp một giải pháp thay thế mã nguồn mở tuyệt vời cho Pusher và Ably cho những ứng dụng thích quản lý máy chủ Web Socket của riêng họ.

Bootstrap 5 Pagination Views

Laravel hiện bao gồm các dạng xem phân trang được xây dựng bằng Bootstrap 5. Để sử dụng các dạng xem này thay vì các dạng xem Tailwind mặc định, bạn có thể gọi phương thức của

Route::get('/categories/{category}', function (Category $category) {
    return $category->value;
});
0 trình phân trang trong phương thức
Route::get('/categories/{category}', function (Category $category) {
    return $category->value;
});
1 của lớp
Route::get('/categories/{category}', function (Category $category) {
    return $category->value;
});
2 của bạn:

return Model::query()
	->whereNotExists(function($query) {
		// $query is a Query\Builder
	})
	->whereHas('relation', function($query) {
		// $query is an Eloquent\Builder
	})
	->with('relation', function($query) {
		// $query is an Eloquent\Relation
	});
8

Improved Ignition Exception Page

Ignition, trang gỡ lỗi ngoại lệ nguồn mở do Spatie tạo, đã được thiết kế lại từ đầu. Ignition mới, cải tiến đi kèm với Laravel 9.x và bao gồm các chủ đề sáng / tối, chức năng "mở trong trình chỉnh sửa" có thể tùy chỉnh và hơn thế nữa.

Hướng dẫn php 8 vs 9 - php 8 so với 9

New Helpers

Laravel 9.x giới thiệu hai chức năng trợ giúp mới, tiện lợi mà bạn có thể sử dụng trong ứng dụng của riêng mình.

str

Hàm

Route::get('/categories/{category}', function (Category $category) {
    return $category->value;
});
3 trả về một thể hiện mới
Route::get('/categories/{category}', function (Category $category) {
    return $category->value;
});
4 chuỗi đã cho. Hàm này tương đương với phương thức
Route::get('/categories/{category}', function (Category $category) {
    return $category->value;
});
5:

return Model::query()
	->whereNotExists(function($query) {
		// $query is a Query\Builder
	})
	->whereHas('relation', function($query) {
		// $query is an Eloquent\Builder
	})
	->with('relation', function($query) {
		// $query is an Eloquent\Relation
	});
9

Nếu không có đối số nào được cung cấp cho hàm

Route::get('/categories/{category}', function (Category $category) {
    return $category->value;
});
3, hàm sẽ trả về một thể hiện của
Route::get('/categories/{category}', function (Category $category) {
    return $category->value;
});
7:

public function getNameAttribute($value)
{
    return strtoupper($value);
}
 
public function setNameAttribute($value)
{
    $this->attributes['name'] = $value;
}
0

to_route

Hàm

Route::get('/categories/{category}', function (Category $category) {
    return $category->value;
});
8 phản hồi HTTP chuyển hướng cho một
enum Category: string
{
    case Fruits = 'fruits';
    case People = 'people';
}
1 được đặt tên nhất định, cung cấp một cách chuyển hướng rõ ràng đến các
enum Category: string
{
    case Fruits = 'fruits';
    case People = 'people';
}
1 được đặt tên từ các
enum Category: string
{
    case Fruits = 'fruits';
    case People = 'people';
}
1 và
enum Category: string
{
    case Fruits = 'fruits';
    case People = 'people';
}
0 của bạn:

public function getNameAttribute($value)
{
    return strtoupper($value);
}
 
public function setNameAttribute($value)
{
    $this->attributes['name'] = $value;
}
1

Nếu cần, bạn có thể chuyển mã trạng thái HTTP sẽ được gán cho chuyển hướng và bất kỳ tiêu đề phản hồi bổ sung nào làm đối số thứ ba và thứ tư cho phương thức

Route::get('/categories/{category}', function (Category $category) {
    return $category->value;
});
8:

public function getNameAttribute($value)
{
    return strtoupper($value);
}
 
public function setNameAttribute($value)
{
    $this->attributes['name'] = $value;
}
2

server.php removed

Một tính năng nhỏ nhưng bây giờ bạn có thể xóa server.php tệp khỏi dự án của mình. Tập tin này chỉ được sử dụng cho

use App\Http\Controllers\OrderController;
 
Route::controller(OrderController::class)->group(function () {
    Route::get('/orders/{id}', 'show');
    Route::post('/orders', 'store');
});
4.server.php tệp khỏi dự án của mình. Tập tin này chỉ được sử dụng cho
use App\Http\Controllers\OrderController;
 
Route::controller(OrderController::class)->group(function () {
    Route::get('/orders/{id}', 'show');
    Route::post('/orders', 'store');
});
4.

Checked / Selected Blade Directives

Trước đây mình đã phải tự viết một helper để kiểm tra trạng thái checked hoặc selected của thẻ input và select, Nhưng giờ đây đã có thể sử dụng @checked và @selected để đơn giản hoá việc đó.checked hoặc selected của thẻ inputselect, Nhưng giờ đây đã có thể sử dụng @checked@selected để đơn giản hoá việc đó.

public function getNameAttribute($value)
{
    return strtoupper($value);
}
 
public function setNameAttribute($value)
{
    $this->attributes['name'] = $value;
}
3

And More...

Xem thêm tại: Trang chính thức Laravel Releases