Laravel
What’s new in Laravel 8 — part 1
自從 Laravel 6 開始遵循 Sematic Versioning 後,版本號就咻咻咻的跳,記得在 7 月準備 laravel conf 的分享時,才 7.21.0,然後九月 Laravel 8 就釋出了,是不是覺得很興奮開心(倍感壓力)啊?
興奮歸興奮,還是要冷靜一下,來看看 Laravel 8 有哪些好玩的新功能,這次就先分享以下五個,我自己看過之後,覺得 Laravel 果然又更方便好用了呢!
- Models 檔案夾
- Migration Squashing
- Model Factory Classes
- Model Factory Relationships
- Maintenance Mode
Models 檔案夾
千呼萬喚始出來!以我自己來說,我習慣不把 models 放在 app 檔案夾裡,雖然說我的 laravel 專案有另外的模組化設計,所以也很少會有獨立、不在模組中的 model,但如果有,我是一定會開一個 Models 檔案夾的,現在終於有了。
Laravel 8 也很貼心,如果不習慣有這個檔案夾存在,可以把它移除,之後當你 make:model
的時候,他也會自動幫你在 app/
底下建立 model,以下程式碼就是在 make:model
時,檢查是否有 app/Models 檔案夾的實作 :
Migration Squashing
不知道大家在用 Laravel 時,有沒有遇過隨著專案需求的更迭、系統的長大,專案中的 migration 檔案愈來愈多,也愈來愈不好管理。如果整合測試環境中,需要每次都重新 migrate,因為 migration 的數量很多,也會因此而佔去不少時間?
Laravel 8 看到大家的痛苦了,新增了一個功能 php artisan schema:dump
,執行這個指令過後可以看到在 database
底下多了一個 schema
的檔案夾,且其中產生了一個叫做 {connection-name}-schema.sql
的檔案。以我的測試為例,connection name 為 mysql,所以被產生的檔案就是 /database/schema/mysql-schema.sql
,其內容就是資料庫 dump 出來的結果:
如果在這之後又建立了新的 migration,在執行 migrate:fresh
時,laravel 將會先執行這個 schema sql 檔案,然後再執行新的 migration。
此外,也可以在建立這個檔案時加上 --prune
,他會在建立 schema檔案後,貼心地幫你移除整個 migrations
檔案夾,其實作如下:
Model Factory Classes
在 Laravel 8 以前,要用 factory 建立資料,其用法如下:
factory(App\User::class)->make();
// or
factory('App\User')->make();
然後在 /database/factories
中,是用 $factory->define
來定義 factory 的。
在 Laravel 8,則將 factory 類別化了,一樣打開 /database/factories/UserFactory.php
,可以看到 UserFactory
已經變成一個 class 了,然後在 app/Models/User.php
中可以看到多用了一個 trait HasFactory
,然後就可以用以下方法來執行 factory:
App\Models\User::factory()->make();
這樣做有什麼好處呢?因為現在 factory 是一個類別,所以就變得很好擴展,例如 Factory States,按照文件中的範例,你可以在 factory class 中定義一個函式:
public function suspended()
{
return $this->state([
'account_status' => 'suspended',
]);
}
而在 definition
函式中,對 account_status
這個欄位可以給一個預設值,例如 active
,而當你想要建立出 account_status
是 suspended
的資料時,只需要在 make 前先叫用 suspended
函式即可。
App\Models\User::factory()->suspended()->make();
當然,你可以定義不止一個 state,需要設定時就叫用,這樣在建立測試資料時,就增加了很多彈性。
Model Factory Relationships
在 Laravel 8 以前,如果 factory 要建立 relationship 的資料,例如在建立使用者時,為他建立關聯這個使用的文章,通常我們會這樣寫:
$users = factory(App\User::class, 3)
->create()
->each(function ($user) {
$user->posts()->save(factory(App\Post::class)->make());
});// 或是$user->posts()->createMany(
factory(App\Post::class, 3)->make()->toArray()
);
但在 Laravel 8 中,只要 Model 中定義好關係,就可以用以下方法建立關聯資料:
$user = User::factory()
->has(Post::factory()->count(3))
->create();// 甚至還提供了語法糖
$user = User::factory()
->hasPosts(3)
->create();
反過來也有對應的方式:
$posts = Post::factory()
->for(User::factory())
->count(3)
->create();// 當然也有相對應的語法糖
$posts = Post::factory()
->forUser()
->count(3)
->create();
Maintenance Mode
在 Laravel 8 以前,維護模式提供了自定義訊息以及允許正常顯示的 IP,例如這樣:
php artisan down --message="Upgrading Database" --allow=127.0.0.1
Laravel 8 取消了 message 與 allow 這兩個設定,取而代之的是更彈性的擴充,例如白名單改為用 secret
來設定,而 message 則是用 render
來取代。
在啟動維護模式時,指定 secret:
php artisan down --secret="ilovelaravel"
然後開啟網站時,在網址加上這個 secret,例如 http://example.com/ilovelaravel
,可以發現網頁會被轉跳為 / ,且 cookie 中多了一個 laravel_maintenance
,如果將這個 cookie 手動刪掉,就會進入維護模式。
在 Laravel 8 啟動維護模式時,預設仍是 503 | SERVICE UNAVAILABLE
,在此之前,只能修改 message,也就是 SERVICE UNAVAILABLE
這一部分。但在 Laravel 8 可以透過 render
參數指定自己想要顯示的樣式,例如可以建立一個叫做 maintenance 的 blade,然後透過 render
來指定維護模式啟動時要顯示這個 blade。如果自己不想切版,Laravel 也很貼心的提供了一些 blade 讓我們用,只要 vendor publish 一下 laravel-errors
就可以使用了。
php artisan vendor:publish // 選擇 laravel-errors
就可以在 views 中看到多了 errors
檔案夾:
然後在啟動維護模式時,指令採用自己想要用的頁面:
php artisan down --render="errors.illustrated-layout"
就可以看到換了一個新的維護模式畫面。當然,我們也可以自行去修改、編輯這些 Laravel 提供的頁面,是不是很方便呢?
Laravel 8 的新功能不止這些,但先到此為止,有機會再分享 part2 (補充: 來了來了,在這裡),以下是這次分享的參考資料,蠻推薦看看的: