如何升級laravel5.4到laravel5.5並使用新特性?
修改composer.json:
"laravel/framework": "5.5.*",
"phpunit/phpunit": "~6.0"
scripts增加:
"post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"@php artisan package:discover"
]
執行composer update -vvv
新特性1: 擴展包自動發現
為擴展包增加了一個自動發現功能。
以barryvdh/laravel-debugbar為例,先刪除這個包。composer remove barryvdh/laravel-debugbar
先把APP里面的Barryvdh\Debugbar\ServiceProvider::class,去掉。
就刪除成功了。
再重新安裝:
我們看github上這個包最新版的
Installing barryvdh/laravel-debugbar (v3.1.0): Downloading (100%)
里面的包的composer.json有這么一個說明:
"extra": {
"branch-alias": {
"dev-master": "3.0-dev"
},
"laravel": {
"providers": [
"Barryvdh\\Debugbar\\ServiceProvider"
],
"aliases": {
"Debugbar": "Barryvdh\\Debugbar\\Facade"
}
}
},
我們看到,在bootstrap/cache/packages.php里面已經寫上了debugbar,並且我們在頁面上也可以看到有debugbar的存在。但是我們並不需要在app.php里面增加debugbar的serviceProvider了。非常方便!!!
就是說,我們引入的包里面,只要有這個extra.laravel的說明,后面的providers和alias會自動增加到框架中去。
新特性2: api resources
這個特性的功能就是把資源直接作為api返回給前端,並且進行需要的包裝。
這里的resource就是返回資源,我們可以創建這么一個返回資源,這個資源會被包裝在data字段中,json,api返回。
比如創建一個PostCollection資源。代表文章集合。
php artisan make:resource PostCollection
我希望返回的api里面有兩個字段:data和meta,data代表的就是文章集合,meta代表的是一些附屬的元數據信息。
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\ResourceCollection;
class PostCollection extends ResourceCollection
{
/**
* Transform the resource collection into an array.
*
* @param \Illuminate\Http\Request
* @return array
*/
public function toArray($request)
{
return parent::toArray($request);
}
public function with($request)
{
return [
'meta' => [
'site' => 'laravel55',
],
];
}
}
在路由中:
Route::get('/api/posts', function () {
return new \App\Http\Resources\PostCollection(\App\Post::all());
});
並且在\App\Post中重新定義toArray()
public function toArray()
{
return [
"id" => $this->id,
"title" => $this->title,
];
}
那么這個時候就返回了:
有人說,其實laravel中在控制器中直接返回對象也就是調用它們的toArray方法,那么如果你把上式的路由修改為:
Route::get('/api/posts', function () {
return new \App\Http\Resources\PostCollection(\App\Post::paginate(3));
});
你就感覺到增加這個"api resource"的方便性了:統一API返回結構,並且讓你少寫了很多代碼。
特性3: command能自動注冊
我們之前自定義的Command需要在Console\Commands\Kernel.php中寫上每個Command:
class Kernel extends ConsoleKernel
{
/**
* The Artisan commands provided by your application.
*
* @var array
*/
protected $commands = [
\App\Console\Commands\ESInit::class
];
現在,不用了,只修改commands函數:
protected function commands()
{
$this->load(__DIR__ . '/Commands');
require base_path('routes/console.php');
}
特性4:驗證規則類
這個規則是為了我們的自定義驗證規則。比如,我們的登錄,需要郵箱后綴為gmail.com才能登錄。那么這個時候我們就需要定義一個驗證規則類:
php artisan make:rule ValidLoginEmail
我們在App\Rules文件夾下面看到ValidLoginEmail類:
class ValidLoginEmail implements Rule
{
/**
* Create a new rule instance.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Determine if the validation rule passes.
*
* @param string $attribute
* @param mixed $value
* @return bool
*/
public function passes($attribute, $value)
{
$strs = explode("@", $value);
if (count($strs) == 2 && $strs[1] == "gmail.com") {
return true;
}
return false;
}
/**
* Get the validation error message.
*
* @return string
*/
public function message()
{
return '郵箱必須是gmail結尾';
}
}
然后再修改loginController的login()的驗證部分:
$this->validate(request(),[
'email' => ['required', new ValidLoginEmail(), 'email'],
'password' => 'required|min:5|max:10',
'is_remember' => 'integer'
]);
效果:
新特性5: request增加了validate方法
還是login方法,我們也可以這樣寫:
public function login(Request $request)
{
// 驗證
$request->validate([
'email' => ['required', new ValidLoginEmail(), 'email'],
'password' => 'required|min:5|max:10',
'is_remember' => 'integer'
]);
不再需要使用
$this->validate(request(),[
這樣做的好處是更語義化了:驗證請求符合下列規則...
新特性6: 自定義Exception增加了render和report方法
在以前,我們自定義一個Exception類,要想這個異常單獨處理,就需要在Handler.php里面的render方法這么寫:
public function render($request, Exception $exception)
{
if ($exception instanceof \App\Exceptions\ForbiddenException) {
return response()->view("exceptions/forbidden");
}
return parent::render($request, $exception);
}
這樣自定義異常定義多了,這個函數就非常冗余。
現在的方法就是,在自定義異常里面定義一下render方法就行
<?php
namespace App\Exceptions;
class ForbiddenException extends \Exception
{
/**
* Report the exception.
*
* @return void
*/
public function report()
{
//
}
/**
* Report the exception.
*
* @param \Illuminate\Http\Request
* @return void
*/
public function render($request)
{
return response()->view("exceptions/forbidden");
}
}
新特性7: 增加了Route::view方法
如果你這個路由什么邏輯都沒有,只是渲染一個模版,那么就很適合使用這個方法。比如創建文章頁面:
原先:
Route::get('/posts/create', '\App\Http\Controllers\PostController@create');
// 創建頁面
public function create()
{
return view("post/create");
}
現在:
// 創建文章
Route::view('/posts/create', 'post/create');
這個功能大贊,能讓人少寫很多代碼。
更多5.5新特性請看:
https://laravel.com/docs/5.5/releases