新版特性
由 學院君 建立于1年前, 最後更新于 1年前
版本号 #2
17909 views
7 likes
2 collects
Laravel 6.0(LTS 版本) 在 Laravel 5.8 的基礎上繼續進行優化,包括引入語義化版本、相容 Laravel Vapor、優化授權響應、支援任務中間件、新增懶集合、優化資料庫子查詢、将前端腳手架提取到獨立的 Composer 包 laravel/ui、以及多個 bug 修複和可用性的提升。
語義化版本
Laravel 架構包 laravel/framework 現在遵循語義化版本标準。這使得架構得以和其他已經遵循該版本标準的 Laravel 擴充包保持一緻,不過 Laravel 的釋出周期将保持不變。
相容 Laravel Vapor
Laravel 6.0 提供了對 Laravel Vapor 的相容,這是一個針對 Laravel 應用的自動擴容無伺服器部署平台。Vapor 對在 AWS Lambda 上管理 Laravel 應用以及與 SQS 隊列、資料庫、Redis 叢集、網絡、CloudFront CDN 進行互動的複雜性進行了抽象。
通過 Ignition 優化異常
Laravel 6.0 支援 Ignition,這個一個開源的錯誤和異常詳情頁項目,由 Freek Van der Herten 和 Marcel Pociot 建立并維護。相對于之前版本的錯誤顯示,Ignition 提供了諸多便捷之處,比如優化了 Blade 錯誤檔案和行号處理、針對常見問題的可執行解決方案、代碼編輯、異常分享、以及經過優化的使用者體驗。
優化授權響應
在之前版本的 Laravel 中,擷取并提供自定義授權消息給終端使用者很困難,主要難點在于如何向終端使用者解釋清楚為什麼特定的請求被拒絕了。在 Laravel 6.0 中,我們可以使用 Gate::inspect 方法和授權響應消息來輕松實作。例如,給定如下政策方法:
public function view(User $user, Flight $flight)
{
return $this->deny('Explanation of denial.');
}
接下來我們可以通過 Gate::inspect 方法擷取授權政策的響應,然後再通過響應示例的 message() 方法擷取授權消息:
$response = Gate::inspect('view', $flight);
if ($response->allowed()) {
// 使用者被授權可以通路航班...
}
if ($response->denied()) {
echo $response->message();
}
此外,當在路由或控制器中使用 $this->authorize 或者 Gate::authorize 方法時,這些自定義的消息會被自動傳回給前端。
任務中間件
任務中間件允許你封裝自定義的隊列任務異常業務邏輯,避免在任務自身進行中混入對應樣闆代碼。例如,在之前的 Laravel 版本中,你可能需要在頻率限制回調中封裝某個任務的 handle 方法處理邏輯:
public function handle()
{
Redis::throttle('key')->block(0)->allow(1)->every(5)->then(function () {
info('Lock obtained...');
// 處理任務...
}, function () {
// 無法擷取到鎖...
return $this->release(5);
});
}
而在 Laravel 6.0 中,該業務邏輯可以被提取到任務中間件中,進而将你的任務 handle 方法從頻率限制中解放出來:
namespace App\Jobs\Middleware;
use Illuminate\Support\Facades\Redis;
class RateLimited
{
public function handle($job, $next)
{
Redis::throttle('key')
->block(0)->allow(1)->every(5)
->then(function () use ($job, $next) {
// Lock obtained...
$next($job);
}, function () use ($job) {
// Could not obtain lock...
$job->release(5);
});
}
}
建立完中間件後,可以通過在任務類的 middleware 方法中傳回中間件數組來将其追加到隊列任務中:
use App\Jobs\Middleware\RateLimited;
public function middleware()
{
return [new RateLimited];
}
懶集合
許多開發者已經使用過 Laravel 功能強大的集合方法了,在 Laravel 6.0 中新引入了一個 LazyCollection 類來對 Collection 類進行補充,LazyCollection 底層基于 PHP 的生成器實作,适用于處理大型資料集。
例如,假設你的應用需要處理 GB 級别的日志檔案,并使用 Laravel 的集合方法來解析日志,這個時候将整個日志檔案一次性讀取到記憶體顯然是不合适的,這個時候懶集合類就派上用場了,它可以每次隻讀取檔案的一小部分到記憶體:
use App\LogEntry;
use Illuminate\Support\LazyCollection;
LazyCollection::make(function () {
$handle = fopen('log.txt', 'r');
while (($line = fgets($handle)) !== false) {
yield $line;
}
})
->chunk(4)
->map(function ($lines) {
return LogEntry::fromLines($lines);
})
->each(function (LogEntry $logEntry) {
// Process the log entry...
});
或者,假設你需要疊代 10000 個 Eloquent 模型執行個體,如果使用傳統的 Laravel 集合,所有 10000 個 Eloquent 模型會同時加載到記憶體中:
$users = App\User::all()->filter(function ($user) {
return $user->id > 500;
});
不過,從 Laravel 6.0 開始,查詢建構器的 cursor 方法已經被更新為傳回 LazyCollection 執行個體,這樣一來,我們就可以像之前一樣執行一次資料庫查詢,但是每次隻會加載一個 Eloquent 模型到記憶體。在這個示例中,filter 回調隻有在疊代完每個使用者時才會執行,進而極大減少記憶體的使用量:
$users = App\User::cursor()->filter(function ($user) {
return $user->id > 500;
});
foreach ($users as $user) {
echo $user->id;
}
Eloquent 子查詢優化
Laravel 6.0 引入了多個資料庫子查詢優化和增強支援。例如,假設我們有一個航班目的地表 destinations 和飛向這些目的地的航班表 flights,flights 表包含了一個 arrived_at 字段來表示航班到達目的地的時間。
使用 Laravel 6.0 提供的新的子查詢功能,我們可以通過一個查詢擷取所有的航班目的地以及最新到達這些目的地的航班名稱:
return Destination::addSelect(['last_flight' => Flight::select('name')
->whereColumn('destination_id', 'destinations.id')
->orderBy('arrived_at', 'desc')
->limit(1)
])->get();
此外,我們還可以使用查詢建構器方法 orderBy 添加的新的子查詢方法基于到達目的地的最晚航班到達時間對所有航班目的地進行排序,同樣,這也可以通過一次資料庫查詢完成:
return Destination::orderByDesc(
Flight::select('arrived_at')
->whereColumn('destination_id', 'destinations.id')
->orderBy('arrived_at', 'desc')
->limit(1)
)->get();
Laravel UI
之前版本 Laravel 提供的典型的前端腳手架代碼現在被提取到獨立的 Composer 擴充包 laravel/ui 中,這樣一來可以讓 UI 腳手架代碼的開發和維護與主架構分離。是以,在預設架構腳手架代碼中,現在已經剔除了 Bootstrap 和 Vue 相關代碼,make:auth 指令也被提取出去。
如果想要恢複之前版本的 Vue/Bootstrap 腳手架代碼,可以安裝 laravel/ui 擴充包,并使用 Artisan 指令 ui 來安裝前端腳手架代碼:
composer require laravel/ui
php artisan ui vue --auth