商業,創業,美食,葡萄酒,閱讀,網路科技。
這是我的 FB粉專 以及 IG,我比較常使用 Threads,歡迎大家追蹤互動~
https://laravel-news.com/laravel-9
今年 (2022) 二月 Laravel 9 發佈了。
從 Laravel 9 開始,major version 每一年更新一次。因為 Laravel 底層有使用 Symfony Framework 的元件,而且 Symfony 每年的 11 月會更新一次,所以 Laravel 目前是訂在隔年的二月更新 major version (這樣可以使用最新的 Symfony 版本)。像這次發布的 Laravel 9 底層是使用 Symfony 6.0。
以下列出 Laravel 9 的一些主要更新和新功能:
PHP 8.0 是 Laravel 9 最低的 PHP 版本要求
這是最根本的前提條件,檢查你的環境是不是 PHP 8.0 以上,才有辦法跑 Laravel 9。
route:list 指令顯示結果的重新設計
php artisan route:list
route:list
指令存在已久,如果 route 數量多而複雜,以前的顯示介面會有點混亂。Laravel 9 重新設計了 route:list
指令的顯示結果。
新的 test 指令選項,顯示測試覆蓋率
php artisan test --coverage
Laravel 的測試是基於 PHPUnit,Laravel 的測試功能存在已經非常久。上面指令會執行測試,並顯示每支程式的測試覆蓋率。
DB 預設使用 Anonymous Migration
Laravel 的 database migration,以前是要自己取 migration class name。但如果因需求變更,刪除再新增同一 DB table,或是多次修改同一 DB table,取 migration class name 就會變成一件麻煩事,migrate 起來的行為也不見得會跟你的邏輯順序相同。
Anonymous Migration 是 Laravel 8 後期推出的功能,Laravel 9 變成專案預設,以後再也不用取 migration class name 了。
新的 string functions
因為 Laravel 9 最低要求 PHP 8.0。PHP 8 新的 string functions: str_contains
, str_starts_with
, str_ends_with
也被引入,包裝成 Laravel 9 string functions: Str::contains
, Str::startsWith
, Str::endsWith
寄信件模組從 Swift Mailer 更新為 Symfony Mailer
Swift Mailer 為 Symfony Framework 的寄件元件,隨著 2021 年 11 月 Symfony 6.0 的推出,改為使用 Symfony Mailer,並停止維護 Swift Mailer。Laravel 9 也隨之改為使用 Symfony Mailer。
Eloquent Accessor / Mutator 有新的寫法
Laravel 8 以前的 Accessor / Mutator,例如你要存取一個 model 裡的 first_name
attribute,要這樣寫
public function getFirstNameAttribute($value)
{
return strtoupper($value);
}
public function setFirstNameAttribute($value)
{
$this->attributes['name'] = $value;
}
Laravel 9 改成
use Illuminate\Database\Eloquent\Casts\Attribute;
// 注意有 return type
public function firstName(): Attribute
{
// 官方文件是寫 Attribute::make(...
// in this case, new 或 make 都可以
return new Attribute(
get: fn ($value) => strtoupper($value),
set: fn ($value) => $value,
);
// 如果你是要 chain methods, 則是要用 Attribute::make(...
// 例如
/*
return Attribute::make(
...
)->shouldCache();
*/
}
用 PHP 8.1 的 enum 做 implicit route binding
https://laravel.com/docs/9.x/routing#implicit-enum-binding
官方文件的 sample code
// Category 為 enum
Route::get('/categories/{category}', function (Category $category) {
return $category->value;
});
可以更漂亮的限制哪些參數是 route 可以允許的, 如果是不允許的參數, 直接 return 404.
用 Route::controller 將同一 controller 不同 route 更好的組織起來
Route::controller(YourController::class)->group(function () {
…. // route 1
…. // route 2
});
不用再重複寫 ControllerName,組織上,程式的簡潔度上都比較好。
用 PHP 8.1 的 enum 做 Eloquent Attribute Casting
官方文件的 sample code
use App\Enums\ServerStatus;
protected $casts = [
'status' => ServerStatus::class,
];
你的 $model->status
不管是存,還是取,都會直接 cast 成一個 enum object.
if ($server->status == ServerStatus::Provisioned)
{
$server->status = ServerStatus::Ready;
$server->save();
}
https://laravel.com/docs/9.x/eloquent-mutators
包含上方的 Accessor / Mutator,以及這邊的 Casting,他們都屬於同一份文件,Laravel 9 在這份文件做了不少更新。
Route parameter scoping
https://laravel.com/docs/9.x/routing#implicit-model-binding-scoping
官方文件的 sample code
Route::get('/users/{user}/posts/{post:slug}', function (User $user, Post $post) {
return $post;
});
如果是這種格式的 route,而且使用 custom key (:slug的部分)。Laravel 會自動 scope 該 user 底下的 posts.
Laravel 9 開始,如果沒使用 custom key,同樣也可以 scope child binding
Route::get('/users/{user}/posts/{post}', function (User $user, Post $post) {
return $post;
})->scopeBindings();
這樣寫法好處是更漂亮、更簡潔的檢查第一、二個參數的 relation.
Full Text Index & query by whereFullText
Laravel 9 開始, 如果使用 MySQL 或 PostgreSQL,可以使用 fullText method 做整段的 index。官方文件的 sample code
$table->text('bio')->fullText();
當 query 時,如果有 full text index 的欄位,可以使用兩個 method:whereFullText、orWhereFullText。官方文件的 sample code
$users = DB::table('users')
->whereFullText('bio', 'web developer')
->get();
Bootstrap 5 Pagination Views
Laravel 9 原生支援 Bootstrap 5 Pagination。在 AppServiceProvider, boot method, call
Paginator::useBootstrapFive();
即可使用 Bootstrap 5 Pagination View。
重新設計的 debug page
Laravel debug page 使用的是 Spatie Ignition,也重新設計了。
2 個新的 helper functions: str & to_route
str() 就是之前的 Str::of(),可以做一些字串的操作。
https://laravel.com/docs/9.x/redirects#redirecting-named-routes
之前 Redirect to Named Route 的 sample code
return redirect()->route('profile', ['id' => 1]);
Laravel 9 新寫法的 sample code
return to_route('users.show', ['user' => 1]);
甚至可以指定 HTTP status code 和 response header
return to_route('users.show', ['user' => 1], 302, ['X-Framework' => 'Laravel']);
結論
這次 Laravel 9 主要是底層語言與模組的更新,程式的寫法上更加簡潔漂亮。另外,如果你的環境是 PHP 8.1 以上,PHP 8.1 enum 的用法也可以參考一下。這次 Laravel 的更新,可能對有軟體工程基礎,對 Laravel 又有經驗的讀者,會比較有參考價值。
商業,創業,美食,葡萄酒,閱讀,網路科技。