# 發行說明
## 版本控制方案
Laravel 的版本控制方案使用以下約定:`主版本號.次版本號.修訂號`。 次版本號框架每六個月(二月和八月)發布,而修訂號版本可能每周發布一次,修訂號版本**不**包含重大更改。
當你從應用程序中或在包中引用 Laravel 框架或者其他組件時,應該始終使用版本約束,例如`5.7.*`,因為 Laravel 的次要版本包含重大更改。但是,我們會努力確保你可以在一天或者更短時間內完成更新。
主版本之間的發布往往需要很多年,每次發布代表框架架構和底層結構發生了根本的改變。而目前并沒有準備開發主版本號的計劃。
## 支持策略
對于 LTS 版本,例如 Laravel 5.5,提供兩年的錯誤修復和三年的安全修復。這些版本提供最長時間的支持和維護。對于一般版本,則只是提供六個月的錯誤修復和一年的安全修復。
| 版本 | 發布時間 | Bug 修復截止時間 | 安全修復截止時間 |
| --- | --- | --- | --- |
| 5.0 | 2015年2月4日 | 2015年8月4日 | 2016年2月4日 |
| 5.1 (LTS) | 2015年6月9日 | 2017年6月9日 | 2018年6月9日 |
| 5.2 | 2015年12月21日 | 2016年6月21日 | 2016年12月21日 |
| 5.3 | 2016年8月23日 | 2017年2月23日 | 2017年8月23日 |
| 5.4 | 2017年1月24日 | 2017年7月24日 | 2018年1月24日 |
| 5.5 (LTS) | 2017年8月30日 | 2019年8月30日 | 2020年8月30日 |
| 5.6 | 2018年2月7日 | 2018年8月7日 | 2019年2月7日 |
| 5.7 | 2018年8月 | 2019年2月 | 2019年8月 |
## Laravel 5.7
Laravel 5.7 繼續在 Laravel 5.6 的基礎上進行繼續改進:「[Laravel Nova](https://nova.laravel.com/)」,可選的郵件認證到認證腳手架, 在授權和策略中對未登錄用戶的支持,控制臺測試的改進,Symfony`dump-server`的集成,可定位的通知,還有各類其他 bug 修復和可用性改進。
### Laravel Nova
[Laravel Nova](https://nova.laravel.com/)是一個基于Laravel應用程序的漂亮的,同類產品中最佳的管理儀表板。 當然,Nova 的主要功能是使用 Eloquent 管理底層數據庫記錄。 此外,Nova 還提供對過濾器,鏡頭,行為,隊列操作,指標,授權,自定義工具,自定義卡片,自定義字段等更多支持。
要了解有關 Laravel Nova 的更多信息,請查看[Nova 網站](https://nova.laravel.com/).
### 郵箱驗證
Laravel5.7 為框架中包含身份驗證的腳手架提供了可選的電子郵件驗證。為了適應該特性,已經將`email_verified_at`時間戳字段添加到框架默認的`users`表的遷移文件中。
為了提示新注冊的用戶驗證他們的郵件,`User`模型應該實現`MustVerifyEmail`接口:
~~~php
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable implements MustVerifyEmail
{
// ...
}
~~~
一旦`User`模型實現`MustVerifyEmail`接口,新注冊的用戶將收到一封包含簽名驗證鏈接的電子郵件。點擊此鏈接后,Laravel 將自動在數據庫中記錄驗證時間,并將用戶跳轉到你剛才的頁面。
`verified`中間件默認添加的應用程序的 HTTP 內核中。這個中間件可以添加到只允許通過驗證的用戶的路由:
~~~php
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
~~~
> {tip} 想了解有關電子郵件驗證的詳情,請查看[完整文檔](https://laravel-china.org/docs/laravel/5.7/verification)。
### 訪客 入口 / 策略
在以前版本的 Laravel 中,授權入口和策略字段為您的應用程序驗證未授權的訪客并返回`false`。現在,你可以通過聲明"可選"類型提示或為用戶參數定義提供`null`默認值來允許訪客通過授權檢查:
~~~php
Gate::define('update-post', function (?User $user, Post $post) {
// ...
});
~~~
### Symfony Dump Server
Laravel5.7 通過[a package by Marcel Pociot](https://github.com/beyondcode/laravel-dump-server)提供 Symfony 的`dump-server`命令集成。運行`dump-server`的 Artisan 命令來啟動:
~~~php
php artisan dump-server
~~~
一旦服務啟動,所有對`dump`命令的調用只會顯示的`dump-server`控制臺窗口,而不是瀏覽器中,以提供在不破壞 HTTP 響應輸出的情況下檢查數據。
### 通知本地化
Laravel 現在可以使用當前語言環境之外的語言發送通知,如果通知是在隊列化狀態下發送的話,它甚至可以記住這個語言環境。
為了實現這個功能,`Illuminate\Notifications\Notification`類目前提供了一個`locale`方法來設置所需的語言。在格式化通知時,應用程序會將語言環境設置為此語言,格式化完畢之后恢復為之前的:
~~~php
$user->notify((new InvoicePaid($invoice))->locale('es'));
~~~
多通知條目的本地化也可通過`Notification`facade 實現:
~~~php
Notification::locale('es')->send($users, new InvoicePaid($invoice));
~~~
### 控制臺測試
Laravel 5.7 可使用`expectsQuestion`方法輕松模擬用戶的控制臺輸入。此外,你也可以通過`assertExitCode`和`expectsOutput`方法來指定退出代碼和期望輸出的文本。 例如,考量如下控制臺命令代碼:
~~~php
Artisan::command('question', function () {
$name = $this->ask('What is your name?');
$language = $this->choice('Which language do you program in?', [
'PHP',
'Ruby',
'Python',
]);
$this->line('Your name is '.$name.' and you program in '.$language.'.');
});
~~~
可以使用如下帶有`expectsQuestion`,`expectsOutput`,還有`assertExitCode`方法的測試用例,來測試上述控制臺命令:
~~~php
/**
* Test a console command.
*
* @return void
*/
public function test_console_command()
{
$this->artisan('laracon')
->expectsQuestion('What is your name?', 'Taylor Otwell')
->expectsQuestion('Which language do you program in?', 'PHP')
->expectsOutput('Your name is Taylor Otwell and you program in PHP.')
->assertExitCode(0);
}
~~~
### URL 生成器 & 回調語法
在給定控制器生成 URL 行為時,Laravel 的 URL 生成器不僅可以支持字符串傳值形式,現在也可支持「回調」的語法了 :
~~~php
action([UserController::class, 'index']);
~~~
### 分頁器鏈接
Laravel 5.7 可以自由控制在分頁器的 URL「窗口」添加多少個鏈接。默認在主分頁鏈接的兩側各有三個鏈接。但是,你可以使用`onEachSide`方法來控制這個數量:
~~~php
{{ $paginator->onEachSide(5)->links() }}
~~~
### 文件系統的讀/寫流
Laravel 的文件系統這次提供了`readStream`和`writeStream`方法:
~~~php
Storage::disk('s3')->writeStream(
'remote-file.zip',
Storage::disk('local')->readStream('local-file.zip')
);
~~~