# 升級導引
- [從 5.2 升級到 5.3](#upgrade-5.3.0)
- [從 5.1 升級到 5.2.0](#upgrade-5.2.0)
- [升級到 5.1.11](#upgrade-5.1.11)
- [升級到 5.1.0](#upgrade-5.1.0)
- [升級到 5.0.16](#upgrade-5.0.16)
- [從 4.2 升級到 5.0](#upgrade-5.0)
- [從 4.1 升級到 4.2](#upgrade-4.2)
- [從 4.1.x 以前版本升級到 4.1.29](#upgrade-4.1.29)
- [從 4.1.25 以前版本升級到 4.1.26](#upgrade-4.1.26)
- [從 4.0 升級到 4.1](#upgrade-4.1)
<a name="upgrade-5.3.0"></a>
## 從 5.2 升級到 5.3
#### 預計升級耗時:2~3 小時
> {note} 我們盡量羅列出每一個不兼容的變更。但因為其中一些不兼容變更只存在于框架很不起眼的地方,事實上只有一小部分會真正影響到你的應用程序。
### PHP & HHVM
Laravel 5.3 需要 PHP 5.6.4 或者更高的版本。由于不包含和 PHP 5.6+ 相同的語言特性,HHVM 不再受到官方支持。
### 棄用的功能
所有被列在 [Laravel 5.2 升級指南](#廢棄清單) 內的廢棄項都已經從框架中徹底移除。請回顧該列表以確保你沒有繼續使用這些廢棄的特性。
### 應用服務提供者
你可以從 `EventServiceProvider`,`RouteSerivceProvider` 和 `AuthServiceProvider` 類的 `boot` 方法上移除參數。任何給定參數的調用都可以被轉化為等效的 [facade](https://laravel-china.org/docs/5.3/facades)。所以,舉個栗子,除了在 `$dispatcher` 參數上調用方法,你可以直接調用 `Event` facade。同樣,除了在 `$router` 參數上調用方法,你可以直接調用 `Route` facade,`$gate` 亦然(可直接調用 `Gate` facade)。
> {note} 當把方法調用轉化為 facades 時,請先在服務提供者頂部引入 facade 類。
### 數組
#### 鍵/值 順序變更
現在,`Arr` 類中的 `first`,`last` 和 `where` 方法將「值」作為第一個參數傳遞給閉包。例如:
```php
Arr::first($array, function ($value, $key) {
return ! is_null($value);
});
```
在 Laravel 之前的版本中,`$key` 被作為第一個參數。由于大多數情況下只需要用到 `$value`,所以
現在我們把它作為第一個參數。你應該在應用程序中做一次「全局搜索」,以確保 `$value` 是第一個被傳遞到閉包的參數。
### Artisan
#### `make:console` 命令
`make:console` 命令已被重命名為 `make:command`。
### 用戶認證
#### 認證腳手架
框架默認提供的兩個認證控制器現在被拆分成了 4 個更小的控制器。這使得每一個控制器職責更加明晰。升級認證控制器最簡單的方法就是直接從 [GitHub 上復制一份新的認證控制器](https://github.com/laravel/laravel/tree/master/app/Http/Controllers/Auth) 到你自己的項目。
同時,你需要在 `routes/web.php` 文件中調用 `Auth::routes()` 方法。該方法會注冊相應的路由到新的認證控制器。
如果你曾對認證控制器進行過編輯修改,那么在升級后別忘了重新設置一遍。例如,你曾修改過用戶認證中的 `guard`,那么你就需要重寫新控制器中的 `guard` 方法。你可以檢查每個認證控制器的特性來決定哪些方法需要被重寫。
> {tip} 如果你沒有自定義過用戶認證控制器,則無需重新設置。
#### 密碼重置郵件
密碼重置郵件現在使用了新的 Laravel 消息通知特性。如果你想自定義在發送密碼重置鏈接時被發送的消息,你可以重寫 `Illuminate\Auth\Passwords\CanResetPassword` trait 的 `sendPasswordResetNotification` 方法。
`User` 模型 **必須** 使用新的 `Illuminate\Notifications\Notifiable` trait,否則密碼重置郵件無法成功發送。
```php
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
}
```
> {note} 不要忘記注冊 `Illuminate\Notifications\NotificationServiceProvider` 到 `config/app.php` 配置文件中的 `providers` 數組。
#### 以 POST 方式登出
`Auth::routes` 方法現在注冊 `POST` 路由到 `/logout`,取代之前的 `GET` 路由。這可以阻止其他網頁應用將你的用戶從你的應用中登出。這里有兩個方案能讓你正確升級到 5.3,要么將所有登出請求都轉為使用 `POST` 動詞,要么注冊你自己的 `GET` 路由到 `/logout`:
```php
Route::get('/logout', 'Auth\LoginController@logout');
```
### 用戶授權
#### 帶類名的策略調用
一些策略方法只接收當前被認證的用戶,而不需要被授權的模型實例。這種情況在授權 `create` 行為時是最常見的。例如,如果你正在創建一個博客,你可能希望檢查一個用戶是否被授權了新建文章的權限。
當定義不需要接受模型實例的策略方法時,比如 `create` 方法,類名將不再作為第二個參數被傳遞到這些方法。你的方法只需要接收被認證的用戶實例:
```php
/**
* Determine if the given user can create posts.
*
* @param \App\User $user
* @return bool
*/
public function create(User $user)
{
//
}
```
#### `AuthorizesResources` Trait
`AuthorizesResources` trait 現已被合并到 `AuthorizesRequests` trait。你需要從 `app/Http/Controllers/Controller.php` 文件中移除 `AuthorizesResources` trait。
### Blade
#### 自定義指令
在 Laravel 之前的版本中,當使用 `directive` 方法注冊自定義 Blade 指令時,被傳遞到指令回調的 `$expression` 包含最外層的括號。在 Laravel 5.3 中,這些最外層的括號將不再被包含在表達式中。請移步 [Blade 擴展](https://laravel-china.org/docs/5.3/blade) 并確保你的自定義 Blade 指令仍然能正常工作。
### 廣播
#### 服務提供者
Laravel 5.3 對事件廣播進行了很多改進。你需要從 [Github](https://raw.githubusercontent.com/laravel/laravel/develop/app/Providers/BroadcastServiceProvider.php) 上復制一份新的 `BroadcastServiceProvider` 到你的 `app/Providers` 目錄,并將它注冊到 `config/app.php` 配置文件的 `providers` 數組里。
### 緩存
#### 擴展閉包綁定 & `$this`
當在閉包中調用 `Cache::extend` 方法時,`$this` 將會被綁定到 `CacheManager` 實例,這允許你從擴展閉包里調用 `Cahche` 的所有方法:
```php
Cache::extend('memcached', function ($app, $config) {
try {
return $this->createMemcachedDriver($config);
} catch (Exception $e) {
return $this->createNullDriver($config);
}
});
```
### Cashier
如果正在使用 Cashier 交易工具包,你需要升級你的 `laravel/cashier` 包到 ~7.0 版本(>=7.0 并且 <8.0)。這一版的 Cashier 只更新了內部方法以兼容 Laravel 5.3,請放心使用。
### 集合
#### 鍵/值 順序變更
集合中的 `first`,`last` 和 `contains` 方法現在將「值」作為第一個參數傳遞給給定閉包。例如:
```php
$collection->first(function ($value, $key) {
return ! is_null($value);
});
```
在 Laravel 之前的版本中,`$key` 被作為第一個參數。由于大多數情況下只需要用到 `$value`,所以
現在我們把它作為第一個參數。你應該在應用程序中做一次「全局搜索」,以確保 `$value` 是第一個被傳遞到閉包的參數。
#### 默認情況下集合的 `where` 匹配方式為「寬松」模式
集合的 `where` 方法由默認的嚴格匹配改為了「寬松」匹配。如果你想要執行嚴格匹配,可以使用 `whereStrict` 方法。
同時,`where` 方法不再接收用于指明「嚴格」匹配的第三個參數。你應該根據需要顯示地調用 `where` 或 `whereStrict` 方法。
### 控制器
#### 類構造器中的 Session
在 Laravel 之前的版本中,盡管你能夠在控制器的類構造器中訪問 session 變量和被認證的用戶實例,但我們從未把這設計為框架的特性。在 Laravel 5.3 中,你無法再這樣使用了,因為這個時候中間件還沒有運行。
作為一種替代方案,你可以在你的控制器類構造方法中定義一個基于中間件的閉包。為了使用這一特性,請先確認你的 Laravel 版本大于等于 5.3.4:
```php
<?php
namespace App\Http\Controllers;
use App\User;
use Illuminate\Support\Facades\Auth;
use App\Http\Controllers\Controller;
class ProjectController extends Controller
{
/**
* All of the current user's projects.
*/
protected $projects;
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware(function ($request, $next) {
$this->projects = Auth::user()->projects;
return $next($request);
});
}
}
```
當然,你也可以選擇在控制器行為中訪問請求的 session 數據或被認證的用戶實例,這可以通過類型提示 `Illuminate\Http\Request` 類來實現:
```php
/**
* Show all of the projects for the current user.
*
* @param \Illuminate\Http\Request $request
* @return Response
*/
public function index(Request $request)
{
$projects = $request->user()->projects;
$value = $request->session()->get('key');
//
}
```
### 數據庫
#### 集合
現在,[查詢構造器](https://laravel-china.org/docs/5.3/queries) 將返回 `Illuminate\Support\Collection` 實例,而不再是簡單的數組。這使得通過查詢構造器和 Eloquent 方式返回的數據類型保持一致。
如果你想繼續返回簡單的 PHP 數組來保持向后兼容,可以在查詢構造器的 `get` 方法后面跟上 `all` 方法。
```php
$users = DB::table('users')->get()->all();
```
#### Eloquent 的 `$morphClass` 屬性
Eloquent 中的 `$morphClass` 屬性現已被移除,取而代之的是定義一個「morph map」。定義一個 morph map 能夠提供對預加載和解析多態關聯額外問題的支持。如果你之前使用了 `$morphClass` 屬性,請用下面的語句遷移到 `morphMap`:
```php
Relation::morphMap([
'YourCustomMorphName' => YourModel::class,
]);
```
例如,你之前定義了如下 `$morphClass`:
```php
class User extends Model
{
protected $morphClass = 'user'
}
```
現在,你應該在 `AppServiceProvider` 的 `boot` 方法中定義如下 `morphMap`:
```php
use Illuminate\Database\Eloquent\Relations\Relation;
Relation::morphMap([
'user' => User::class,
]);
```
#### Eloquent `save` 方法
如果模型自上一次被取得或保存后沒有被做過任何修改,Eloquent 的 `save` 方法將返回 `false`。
#### Eloquent Scopes
現在,Eloquent scopes 將遵守 scope 條件中的前導布爾值。例如,如果你用一個 `orWhere` 條件開始你的 scope,它將不再被轉成正常的 `where`。如果你使用了這一特性(比如在一個循環中添加多個 `orWhere` 條件),你需要確保第一個條件是正常的 `where` 來避免布爾值導致的邏輯問題。
如果你的 scopes 使用的第一個條件是 `where`,不需要做任何修改。你可以用查詢構造器的 `toSql` 方法來驗證你的查詢語句。
```php
User::where('foo', 'bar')->toSql();
```
#### Join 子句
`JoinClause` 類已經被通過重寫來和查詢構造器保持一致的語法。`on` 閉包中可選的 `$where` 參數現已被移除。如果要添加一個「where」條件,你必須顯示地調用 [查詢構造器](https://laravel-china.org/docs/5.3/queries#Where-Clauses) 提供的 `where` 方法:
```php
$query->join('table', function ($join) {
$join->on('foo', 'bar')->where('bar', 'baz');
});
```
現在,`on` 子句的操作符將會被驗證并且不能再包含非法值。如果你之前使用了這一特性(比如 `$join->on('foo', 'in', DB::raw('("bar")'))`),現在需要用適當的 where 子句重寫條件:
```php
$join->whereIn('foo', ['bar']);
```
`$bindings` 屬性同樣被移除了。可以用 `addBinding` 方法來直接操作 join 綁定:
```php
$query->join(DB::raw('('.$subquery->toSql().') table'), function ($join) use ($subquery) {
$join->addBinding($subquery->getBindings(), 'join');
});
```
### 加密
#### Mcrypt 加密器已被移除
Mycrypt 加密器已經在發行于 2015 年 6 月的 Laravel 5.1.0 中被棄用了。它在 Laravel 5.3.0 中被徹底移除,取而代之的是新的基于 OpenSSL 的加密方案,該方案從 Laravel 5.1.0 開始就已經是默認的加密方案了。
如果你仍然在 `config/app.php` 配置文件中使用基于 `cipher` 的 Mycrypt,你需要升級 cipher 到 `AES-256-CBC` 并且設置你的密鑰為 32 字符長的隨機字符串,你可以通過 `php artisan key:generate` 幫你自動生成。
如果你在數據庫中使用 Mcrypt 加密器來存儲加密后的數據,你可以通過安裝 `laravel/leagacy-encrypter` [包](https://github.com/laravel/legacy-encrypter) 來保留 Mcrypt 加密器。你應該使用這個包來解密你的數據,并用新的 OpenSSL 加密器來重新加密。例如,你可以執行像下面的 [自定義 Artisan 命令](https://laravel-china.org/docs/5.3/artisan):
```php
$legacy = new McryptEncrypter($encryptionKey);
foreach ($records as $record) {
$record->encrypted = encrypt(
$legacy->decrypt($record->encrypted)
);
$record->save();
}
```
### 異常處理器
#### 類構造器
現在,異常處理器的基類需要一個 `Illuminate\Container\Container` 實例來傳遞它的構造器。只有當你在 `app/Exceptions/Handler.php` 文件中使用了 `__construct` 方法時,這個變更才會影響你的應用程序。如果你使用了該方法,現在需要傳遞一個容器實例到 `parent::__construct` 方法:
```php
parent::__construct(app());
```
#### 未認證的方法
你應該添加 `unauthenticated` 方法到你的 `App\Exceptions\Handler` 類中。這個方法會將用戶認證異常轉成 HTTP 響應:
```php
/**
* Convert an authentication exception into an unauthenticated response.
*
* @param \Illuminate\Http\Request $request
* @param \Illuminate\Auth\AuthenticationException $exception
* @return \Illuminate\Http\Response
*/
protected function unauthenticated($request, AuthenticationException $exception)
{
if ($request->expectsJson()) {
return response()->json(['error' => 'Unauthenticated.'], 401);
}
return redirect()->guest('login');
}
```
### 中間件
#### `can` 中間件命名空間變更
HTTP Kernel 文件的 `$routeMiddleware` 屬性中的 `can` 中間件,應該被更新為下面的類:
```php
'can' => \Illuminate\Auth\Middleware\Authorize::class,
```
#### `can` 中間件認證異常
現在,如果用戶未被認證 `can` 中間件會拋出一個 `Illuminate\Auth\AuthenticationException` 實例。如果你之前是手動去捕獲一個其他類型的異常的話,現在需要更新為捕獲該異常。大多數情況下,這個變更不會影響你的應用程序。
#### 綁定替代中間件
現在,路由模型綁定使用中間件來實現。所有的應用程序應該添加 `Illuminate\Routing\Middleware\SubstituteBindings` 到 `app/Http/Kernel.php` 的 `web` 中間件組:
```php
\Illuminate\Routing\Middleware\SubstituteBindings::class,
```
同時,你應該為綁定替代注冊路由中間件到 HTTP kernel 文件的 `$routeMiddleware` 屬性中:
```php
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
```
完成路由中間件注冊后,還需把它添加到 `api` 中間件組:
```php
'api' => [
'throttle:60,1',
'bindings',
],
```
### 消息通知
#### 安裝
Laravel 5.3 包含了一個新的、基于驅動的消息通知系統。首先,你應該向 `config/app.php` 配置文件的 `providers` 數組注冊 `Illuminate\Notifications\NotificationServiceProvider`。
然后,向 `config/app.php` 配置文件的 `aliases` 數組添加 `Illuminate\Support\Facades\Notification` facade。
最后,在你期望接受消息通知的模型里使用 `Illuminate\Notifications\Notifiable` trait。
### 分頁
#### 自定義
與之前的 Laravel 5.x 相比,在 Laravel 5.3 中自定義分頁器生成的 HTML 變得更加容易。不再需要定義一個「Presenter」,現在你只要定義一個簡單的 Blade 模板。自定義分頁視圖最簡單的方法是使用 `vendor:publish` 命令來導出分頁視圖到 `resources/views/vendor` 目錄下:
```php
php artisan vendor:publish --tag=laravel-pagination
```
該命令會把視圖放到 `resources/views/vendor/pagination` 目錄下。目錄下的 `default.balde.php` 文件對應默認的分頁視圖。只需編輯該文件就能修改分頁 HTML。
請移步 [分頁](https://laravel-china.org/docs/5.3/pagination) 獲取更多信息。
### 隊列
#### 配置
在你的隊列配置中,所有的 `expire` 配置項應該被重命名為 `retry_after`。同樣,Beanstalk 配置文件的 `ttr` 項也應該被重命名為 `retry_after`。這一名字的變更讓我們更容易理解這個配置項的作用。
#### 閉包
隊列閉包不再被支持。如果你正在你的應用程序中使用隊列閉包,請把閉包轉成一個類,然后把類的實例添加到隊列:
```php
dispatch(new ProcessPodcast($podcast));
```
#### 集合序列化
現在,`Illuminate\Queue\SerializesModels` trait 能夠正確地序列化 `Illuminate\Database\Eloquent\Collection` 實例。對于絕大多數應用,這個變更不會造成兼容性問題。然而,如果你的應用程序完全依賴于那些不是通過隊列任務從數據庫重新檢索出來的集合的話,你應該驗證這一變更不會對你的應用程序造成負面影響。
#### 守護進程
調用 Artisan `queue:work` 命令時不再需要指定 `--daemon` 選項。`php artisan queue:work` 命令默認以守護模式運行。如果你希望任務只被執行一次,可以在命令后面指定 `--once` 選項:
```php
// Start a daemon queue worker...
php artisan queue:work
// Process a single job...
php artisan queue:work --once
```
#### 事件數據變更
像 `JobProccessing` 和 `JobProcessed` 這類的隊列任務事件不再包含 `$data` 屬性。你應該用 `$event->job->payload()` 方法來獲取事件的數據。
#### 任務表
如果你在 `config/queue.php` 中使用 `database` 驅動來存儲隊列任務,你需要在 `jobs` 表中刪除 `jobs_queue_reserved_reserved_at_index` 索引,并刪除 `reserved` 列,然后對 `queue` 和 `reserved_at` 列添加一個復合索引。
#### 執行失敗的任務表
同上,如果使用了 `database` 驅動,需要在 `failed_jobs` 表中增加 `exception` 列,類型為 `LONGTEXT`。顧名思義,該列將會被用來保存導致任務失敗的異常。
#### 序列化模型
通常來說,Laravel 中的隊列任務是通過傳遞一個新的任務實例到 `Queue::push` 方法來實現的。然而,有些應用可能使用了下面的老舊語法:
```php
Queue::push('ClassName@method');
```
如果你使用了該語法,隊列將不會再自動序列和反序列化 Eloquent 模型。如果你希望 Eloquent 模型仍能被隊列自動序列化,那么請添加 `Illuminate\Queue\SerializesModels` trait 到你的任務類,并使用新的 `push` 語法:
```php
Queue::push(new ClassName);
```
### 路由
#### 資源參數默認為單數形式
在之前的版本中,使用 `Route::resource` 注冊的路由參數未被「單數化」。這會在注冊路由模型綁定時導致一些不可預期的行為。例如,給定以下 `Route::resource` 調用:
```php
Route::resource('photos', 'PhotoController');
```
該 URI 的 `show` 路由將被定義為:
```php
/photos/{photos}
```
在 Laravel 5.3 中,所有的資源路由參數默認都被單數化了。所以,當我們調用 `Route::resource` 時將注冊如下的 URI:
```php
/photos/{photo}
```
如果你想保持之前的形式,請在 `AppServiceProvider` 中調用 `singularResourceParameters` 方法:
```php
use Illuminate\Support\Facades\Route;
Route::singularResourceParameters(false);
```
#### 資源路由名稱不再受前綴影響
對于那些綁定到 `Route::resource` 的路由名稱,URL 前綴不再對其產生影響,因為這一行為違反了優先使用路由名稱的目的。
如果你在一個指定 `prefix` 選項的 `Route::group` 里使用了 `Route::resource`,請檢查所有的 `route` helper 和 `UrlGenerator::route` 調用,確保沒有在路由名稱前添加 URI 前綴。
如果這一變更導致產生兩個相同名稱的路由,你有兩個選擇。要么,在調用 `Route::resource` 時用 `names` 選項為路由指定自定義名稱。請移步 [資源路由文檔](https://doc.laravel-china.org/docs/5.3/controllers#resource-controllers) 或取更多信息。或者,你可以添加 `as` 選項到路由組:
```php
Route::group(['as' => 'admin.', 'prefix' => 'admin'], function () {
//
});
```
### 驗證
#### 表單請求異常
現在,當表單請求驗證失敗時,Laravel 將拋出一個 `Illuminate\Validation\ValidationException` 實例來取代之前的 `HttpException`。如果你曾在代碼中手動捕獲 `HttpException` 實例,你現在需要在 `catch` 語句塊中將其更新為 `ValidationException`。
#### Nullable
當驗證數組、布爾值、整形、數字和字符串時,`null` 將不再被認為是一個合法值,除非規則集里包含了新的 `nullable` 規則:
```php
Validate::make($request->all(), [
'field' => 'nullable|max:5',
]);
```
<a name="upgrade-5.2.0"></a>
## 從 5.1 升級到 5.2.0
#### 估計升級需耗時:少于 1 小時
> **注:** 這里我們會把所有框架中的破壞性變更羅列出來,但并不代表所有的這些變更都會危及你的應用程序。
### 更新依賴
在 `composer.json` 中指定 `laravel/framework 5.2.*`。
增加 `"symfony/dom-crawler": "~3.0"` 和 `"symfony/css-selector": "~3.0"` 到 `composer.json` 文件的 `require-dev` 部分。
### 用戶認證
#### 配置文件
你需要更新配置文件 `config/auth.php`,內容參照 [https://github.com/laravel/laravel/blob/master/config/auth.php](https://github.com/laravel/laravel/blob/master/config/auth.php)
先覆蓋最新的配置信息,然后把配置選項修改為你需要的值,如果你還準備使用經典的 Laravel 5.1 基于 Eloquent 的認證體系,大部分選項都應該保持不變。
在新的 `auth.php` 配置文件中,要特別注意 `passwords.users.email` 配置項,由于在 Laravel 5.2 對 email 視圖路徑做了修改,因此要確保該視圖路徑與應用實際的路徑相匹配,如果不匹配的話要更新該配置值。
#### Contracts
如果你實現了 `Illuminate\Contracts\Auth\Authenticatable` 契約但沒有使用 `Authenticatable` trait 的話,那么你需要添加一個新的 `getAuthIdentifierName` 方法到該契約實現類。通常,該方法返回認證實體的主鍵字段名,如:`id`。
除非你手動實現了此接口,否則這應該影響不到你的應用程序。
#### 自定義驅動
如果你使用了 `Auth::extend` 自定義獲取用戶的方法,你現在應該使用 `Auth::provider` 來自定義用戶提供者。一旦你自定義了提供者,就要在新的 `auth.php` 配置文件中的 `providers` 數組中配置該提供者。
更多信息,請查看 [完整的授權文檔](/docs/{{version}}/authentication).
#### 重定向
`loginPath()` 方法已從 `Illuminate\Foundation\Auth\AuthenticatesUsers` 中移除,所以現在沒必要在你的 `AuthController` 控制器中設置 `$loginPath` 變量。負責授權的 trait 默認情況下會在發生錯誤時重定向會上一個請求路徑。
### 授權
`Illuminate\Auth\Access\UnauthorizedException` 被重命名為 `Illuminate\Auth\Access\AuthorizationException`。
如果你之前沒有手動捕獲該異常,那么這一改變對之前代碼沒有什么影響。
### 集合
#### Eloquent 集合
調用 Eloquent 集合實例的 `pluck`、`keys`、`zip`、`collapse`、`flatten`、`flip` 方法,現在會返回集合基類 `Illuminate\Support\Collection`。
#### 保留鍵名
`slice`, `chunk`, 和 `reverse` 方法現在會保留集合的鍵名,如果你不想這些方法保留鍵名,使用 `集合實例` 調用 `values` 方法即可。
### Composer 類
`Illuminate\Foundation\Composer` 類現在被移動到 `Illuminate\Support\Composer`,如果你沒有在代碼中使用該類,那么這一改變對程序沒有影響。
### 命令和處理器
#### 自處理命令
在創建定時任務或者命令時不再需要實現 `SelfHandling` 契約,所有任務現在默認都是自處理的,因此你可以移除該接口。
#### 獨立的命令 & 處理器
Laravel 5.2 命令總線模式現在只支持自處理命令,不再支持獨立的命令和處理器。
如果你想要繼續使用獨立的命令和處理器,可以安裝提供向后兼容支持的 Laravel Collective 包:[https://github.com/LaravelCollective/bus](https://github.com/laravelcollective/bus)
### 配置信息
#### `env` 環境變量
在配置文件 `app.php` 中添加 `env` 配置項,如下:
'env' => env('APP_ENV', 'production'),
#### 緩存和 `env` 設置項
如果你在開發過程中使用 `config:cache` 命令,**必須** 保證只是在配置文件中調用了 `env` 函數,而不是在應用程序的其它地方。
如果你在應用程序中調用了 `env` 函數,強烈建議添加適當的配置值到配置文件,然后在該位置調用 `env`,從而允許你將 `env` 調用改為 `config` 調用。
#### 編譯文件
請把以下兩行從你的 `files` 數組中移除,如果你的 `config/compile.php` 文件有出現這兩行的話:
realpath(__DIR__.'/../app/Providers/BusServiceProvider.php'),
realpath(__DIR__.'/../app/Providers/ConfigServiceProvider.php'),
不刪除的話,可能會在運行 `php artisan optimize` 的時候觸發 `service providers listed here do not exist` 錯誤。
### CSRF 驗證
在單元測試中不再自動進行 CSRF 驗證,當然這一改變對你的應用程序代碼沒什么影響。
### 數據庫
#### MySQL 日期
自 MySQL 5.7 以后,默認 `strict` 模式是開啟的,所以已經不再支持 `0000-00-00 00:00:00` 作為默認的日期值。所有的 `timestamp` 類型的字段在入庫的時候都應該是正確的日期格式。
你可以在數據庫遷移中使用 `useCurrent` 方法默認使用當前時間,或者設置字段為 `nullable` 來接受 `null` 值:
$table->timestamp('foo')->nullable();
$table->timestamp('foo')->useCurrent();
$table->nullableTimestamps();
#### MySQL JSON 字段類型
在 MySQL 驅動下,`json` 字段類型現在創建真實的 JSON 字段類型,如果你沒有使用 MySQL 5.7 或者以上版本的話,將無法使用此字段。你可以使用 `text` 字段類型作為替代。
#### 數據填充
當運行數據庫填充時,默認情況下,所有的 Eloquent 數據模型現在都是 `unguarded` 的,在之前的版本中,你需要手動調用 `Model::unguard()` 。
如果你還想在運行數據填充時開啟 `guard` 模式的話,請在 `DatabaseSeeder` 類的最開始部分調用 `Model::reguard()` 。
### Eloquent
#### 日期轉化
當調用模型或模型集合的 `toArray` 方法時,任何添加到 `$casts` 的屬性,如 `date` 或 `datetime`,現在都會被轉化為字符串。這使在 `$dates` 數組中制定的日期轉化規則保持一致。
#### 全局作用域
我們重寫了全局作用域的實現以便于更方便的使用,全局作用域不再需要 `remove` 方法,因此可以在所有你使用到該方法的地方將其移除。
如果你曾在 Eloquent 查詢構建器上調用過了 `getQuery` 方法以獲取底層查詢構建器實例,現在應該改為調用 `toBase` 方法。
如果你因為某種原因直接調用了 `remove` 方法,需要將其改成 `$eloquentBuilder->withoutGlobalScope($scope)` 這種方式來調用。
在 Eloquent 查詢構建器中新增了 `withoutGlobalScope` 和 `withoutGlobalScopes` 方法,任何調用 `$model->removeGlobalScopes($builder)` 的地方現在都要改成 `$builder->withoutGlobalScopes()`。
#### 主鍵
默認情況下,Eloquent 會假設你的主鍵是 `integer` 整數類型,并且會強制類型為 `integer` 整數類型,如果你的主鍵不是整數類型,請設置類屬性 `$incrementing` 為 `false`:
/**
* 設定主鍵是否為整數類型
*
* @var bool
*/
public $incrementing = true;
### 事件
#### 核心事件對象
Laravel 的一些核心事件現在使用事件對象取代之前的事件名稱以及動態參數,下面是原來的事件名稱與現在的事件對象對應關系:
Old | New
------------- | -------------
`artisan.start` | `Illuminate\Console\Events\ArtisanStarting`
`auth.attempting` | `Illuminate\Auth\Events\Attempting`
`auth.login` | `Illuminate\Auth\Events\Login`
`auth.logout` | `Illuminate\Auth\Events\Logout`
`cache.missed` | `Illuminate\Cache\Events\CacheMissed`
`cache.hit` | `Illuminate\Cache\Events\CacheHit`
`cache.write` | `Illuminate\Cache\Events\KeyWritten`
`cache.delete` | `Illuminate\Cache\Events\KeyForgotten`
`connection.{name}.beginTransaction` | `Illuminate\Database\Events\TransactionBeginning`
`connection.{name}.committed` | `Illuminate\Database\Events\TransactionCommitted`
`connection.{name}.rollingBack` | `Illuminate\Database\Events\TransactionRolledBack`
`illuminate.query` | `Illuminate\Database\Events\QueryExecuted`
`illuminate.queue.before` | `Illuminate\Queue\Events\JobProcessing`
`illuminate.queue.after` | `Illuminate\Queue\Events\JobProcessed`
`illuminate.queue.failed` | `Illuminate\Queue\Events\JobFailed`
`illuminate.queue.stopping` | `Illuminate\Queue\Events\WorkerStopping`
`mailer.sending` | `Illuminate\Mail\Events\MessageSending`
`router.matched` | `Illuminate\Routing\Events\RouteMatched`
這些事件對象傳入參數和 Laravel 5.1 的事件處理器 **完全** 一樣,例如,如果你在 Laravel 5.1.* 中使用了 `DB:listen` 事件,在 5.2 中更新代碼如下:
DB::listen(function ($event) {
dump($event->sql);
dump($event->bindings);
});
你可以去檢查每個事件對象類去查看它們的公有屬性。
### Exception Handling
`App\Exceptions\Handler` 類的 `$dontReport` 屬性應該被更新為至少包含以下異常:
use Illuminate\Validation\ValidationException;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Symfony\Component\HttpKernel\Exception\HttpException;
/**
* A list of the exception types that should not be reported.
*
* @var array
*/
protected $dontReport = [
AuthorizationException::class,
HttpException::class,
ModelNotFoundException::class,
ValidationException::class,
];
### 幫助函數
`url()` 當你沒傳參調用時,會返回 `Illuminate\Routing\UrlGenerator` 實例。
### 隱式模型綁定
Laravel 5.2 支持「隱式模型綁定」,以便在路由和控制器中基于 URI 標識符自動注入模型實例。然而,這也改變了路由和控制器中類型提示模型實例這一行為。
如果你之前在路由或控制器中類型提示了模型實例,并且希望注入一個空的模型實例,那么現在應該移除這個類型提示,然后在路由或控制器中直接創建一個新的模型實例;否則,Laravel 將會基于路由 URI 的標識符試圖從數據庫獲取一個已存在的模型實例。
### IronMQ
IronMQ 隊列驅動被移動到自己的擴展包中:
[http://github.com/LaravelCollective/iron-queue](http://github.com/laravelcollective/iron-queue)
### Jobs / Queue
`php artisan make:job` 命令現在默認會創建一個隊列任務類,如果你想要創建一個 `同步任務`(非隊列),請在使用該命令時加上 `--sync` 選項。
### 郵件
郵件配置中移除了 `pretend` 選項,取而代之的,使用 `log` 郵件驅動執行和 `pretend` 同樣的功能,并且 `log` 驅動能提供更多的郵件相關的信息。
### 分頁
為了與框架生成的其它 URL 保持一致,分頁 URL 不再包含斜杠,這一改變對應用代碼不產生任何影響。
### 服務提供者
請在 `app.php` 的 `providers` 數組中移除以下兩個服務提供者:
`Illuminate\Foundation\Providers\ArtisanServiceProvider`
`Illuminate\Routing\ControllerServiceProvider`
### Sessions
因為 Laravel 5.2 認證系統更新的原因,所有現存的會話都將失效。
#### 數據庫 Session 驅動
我們為框架編寫了新的 `database` Session 驅動,該驅動包含更多的用戶信息,例如用戶 ID、IP 地址以及用戶瀏覽器信息,如果你想要繼續使用之前的 `database` 驅動,需要在配置文件 `session.php` 中修改驅動為 `legacy-database`。
如果你想要使用新的驅動,還需要添加 `user_id (nullable integer)`、`ip_address (nullable string)` 以及 `user_agent (text)` 字段到存放 Session 的數據表中。
### Stringy
框架不再內置 `Stringy` 庫,如果要在應用中使用,你需要通過 Composer 手動安裝。
### 表單驗證
#### 異常類型
`ValidatesRequests` trait 現在會拋出 `Illuminate\Foundation\Validation\ValidationException` 異常以取代之前的 `Illuminate\Http\Exception\HttpResponseException`。
如果你沒有手動捕獲該異常,那么這對之前的代碼沒有影響。
### 廢棄清單
下面這些功能在 Laravel 5.2 中被廢棄,在 Laravel 5.3 中會被徹底移除:
- `Illuminate\Contracts\Bus\SelfHandling` 契約,現在可以從任務(Job)中移除。
- 集合的 `lists` 方法被重命名為 `pluck`,方法的功能保持一致。
- 隱式控制器路由注冊 `Route::controller` 被廢棄。在路由文件中請使用明確指定的路由注冊。此功能很有可能會被整理成擴展包的形式提供。
- `get`, `post` 還有其他的路由輔助函數被廢棄,請使用 `Route` facade 作為替代。
- Laravel 5.1 的 `database` session 驅動已經被重命名為 `legacy-database`,并且將會被移除,請查看上文關于 `database` session 驅動以獲取更多信息.
- `Str::randomBytes` 方法被廢棄,會被 PHP 原生 `random_bytes` 取代。
- `Str::equals` 方法被廢棄,會被 PHP 原生 `hash_equals` 取代。
- `Illuminate\View\Expression` 被廢棄,會被 `Illuminate\Support\HtmlString` 取代。
- `WincacheStore` 緩存驅動已被移除。
<a name="upgrade-5.1.11"></a>
## 升級到 5.1.11
Laravel 5.1.11 現支持 [授權](/docs/{{version}}/authorization) 及 [授權策略](/docs/{{version}}/authorization#policies)。要將這些功能添加到現有的 Laravel 5.1 應用程序中是相當容易的。
> **注意:**這些升級是 **可選的**,忽略它們并不會影響你的應用程序。
#### 創建 Policies 目錄
首先,在你的應用程序創建一個空的 `app/Policies` 目錄。
#### 創建并注冊 AuthServiceProvider 與 Gate Facade
在你的 `app/Providers` 目錄創建一個 `AuthServiceProvider`。你可以 [從 GitHub](https://raw.githubusercontent.com/laravel/laravel/master/app/Providers/AuthServiceProvider.php) 獲取默認的內容,請注意,如果你的應用程序使用自定的命名空間的話,請修改提供者的命名空間。創建完成后,請務必在你的 `app.php` 配置文件的 `providers` 數組注冊它。
同樣的,你必須在你的 `app.php` 配置文件的 `aliases` 數組注冊 `Gate` facade:
'Gate' => Illuminate\Support\Facades\Gate::class,
#### 更新用戶模型
然后,在你的 `App\User` 模型使用 `Illuminate\Foundation\Auth\Access\Authorizable` trait 及 `Illuminate\Contracts\Auth\Access\Authorizable` contract:
<?php
namespace App;
use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Foundation\Auth\Access\Authorizable;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
class User extends Model implements AuthenticatableContract,
AuthorizableContract,
CanResetPasswordContract
{
use Authenticatable, Authorizable, CanResetPassword;
}
#### 更新基礎控制器
接著,更新 `App\Http\Controllers\Controller` 基礎控制器,讓它使用 `Illuminate\Foundation\Auth\Access\AuthorizesRequests` trait:
<?php
namespace App\Http\Controllers;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
abstract class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
}
<a name="upgrade-5.1.0"></a>
## 升級到 5.1.0
#### 估計升級需耗時:少于 1 小時
### 更新 `bootstrap/autoload.php`
將 `bootstrap/autoload.php` 里的 `$compiledPath` 變量按照以下方式更新:
$compiledPath = __DIR__.'/cache/compiled.php';
### 創建 `bootstrap/cache` 目錄
在你的 `bootstrap` 目錄里,創建一個 `cache` 目錄 (`bootstrap/cache`)。放置一個有以下內容的 `.gitignore` 文件在這個目錄:
*
!.gitignore
這個目錄必須為可寫的,框架會暫時存放如 `compiled.php`、`routes.php`、`config.php` 和 `services.json` 等文件在此目錄。
### 添加 `BroadcastServiceProvider` 提供者
在你的 `config/app.php` 配置文件里面,增加 `Illuminate\Broadcasting\BroadcastServiceProvider` 到 `providers` 數組里。
### 認證
如果你有使用內置的 `AuthController`,此控制器使用了 `AuthenticatesAndRegistersUsers` trait,你會需要對新用戶如何創建跟驗證做一些修改。
首先,你不再需要傳遞 `Guard` 和 `Registrar` 實例到基底構造器。你可以從控制器的構造器完全移除這些依賴。
第二,已經不再需要 Laravel 5.0 中使用的 `App\Services\Registrar` 類。你可以簡單的從這個類直接復制你的 `validator` 和 `create` 方法粘貼至你的 `AuthController`。這些方法不需要做其它修改。你必須確定有在你的 `AuthController` 頂端引入 `Validator` facade 跟你的 `User` 模型。
#### 密碼控制器
內置的 `PasswordController` 的構造器不再需要任何依賴。你可以把 5.0 下需要的依賴都移除。
### 驗證
如果你在基底控制器類上重寫了 `formatValidationErrors` 方法,你現在應該把類型提示改成 `Illuminate\Contracts\Validation\Validator` contract 來取代具體的 `Illuminate\Validation\Validator` 實例。
同樣地,如果你在基底表單請求類上重寫了 `formatErrors` 方法,你現在應該把類型提示改成 `Illuminate\Contracts\Validation\Validator` contract 來取代具體的 `Illuminate\Validation\Validator` 實例。
### Eloquent
#### `create` 方法
Eloquent 的 `create` 方法現在可以不帶任何參數調用。如果你有在自己的模型重寫了 `create` 方法,請把 `$attributes` 參數的默認值設置成空數組:
public static function create(array $attributes = [])
{
// 你的自定義實現
}
#### `find` 方法
如果你在自己的模型中重寫了 `find` 方法并在方法中調用了 `parent::find()`,現在則應該把它改成調用 Eloquent 查詢語句構造器上的 `find` 方法:
public static function find($id, $columns = ['*'])
{
$model = static::query()->find($id, $columns);
// ...
return $model;
}
#### `lists` 方法
`lists` 方法現在返回一個 `Collection` 實例而不是 Eloquent 查找用的一般數組。如果你想要把 `Collection` 轉換成一般數組,請使用 `all` 方法:
User::lists('id')->all();
請注意查詢語句構造器的 `lists` 方法返回的是一個數組。
#### 日期格式
以前,Eloquent 日期字段的保存格式可以借助重寫模型上的 `getDateFormat` 方法來修改。現在仍然可以這么做。然而,為了方便起見,你可以直接在模型上指定 `$dateFormat` 屬性來取代重寫方法。
當序列化模型成 `array` 或 JSON 時,也會采用該日期格式。當從 Laravel 5.0 遷移到 5.1 時,這可能會改變你的 JSON 序列化的日期字段格式。要想針對序列化模型設置特定的日期格式,你需要在你的模型上重寫 `serializeDate(DateTime $date)` 方法。這個方法可以讓你在不改變日期字段保存格式的情況下,精細的控制 Eloquent 序列化格式。
### 集合類
#### `sort` 方法
`sort` 方法現在會返回全新的集合實例,而不是修改原有的集合:
$collection = $collection->sort($callback);
#### `sortBy` 方法
`sortBy` 方法現在會返回一個全新的集合實例而不會去改動到現有的集合:
$collection = $collection->sortBy('name');
#### `groupBy` 方法
`groupBy` 方法現在會返回 `Collection` 實例給父 `Collection` 的每一個元素。如果你想要把所有元素轉換回一般數組,你可以通過 `map` 來處理:
$collection->groupBy('type')->map(function($item)
{
return $item->all();
});
#### `lists` 方法
`lists` 方法現在返回一個 `Collection` 實例而不是一個一般數組。如果你想要把 `Collection` 轉換成一般數組,請使用 `all` 方法:
$collection->lists('id')->all();
### 命令和處理進程
`app/Commands` 目錄已經被改名成 `app/Jobs`。然而你并不需要把所有的命令移動到新的位置,且可以繼續用 `make:command` 和 `handler:command` Artisan 命令來生成類。
`app/Handlers` 目錄已經被改名成 `app/Listeners` 并且現在只包含事件監聽者。不需要移動或重命名現有的命令和事件處理進程,并且可以繼續使用 `handler:event` 命令來生成事件處理進程。
借由 Laravel 5.0 目錄結構提供的向下兼容性,你可以先升級你的應用程序到 Laravel 5.1,然后在你或你的團隊方便的時候再慢慢地將你的事件跟命令升級到它們的新位置上。
### Blade
`createMatcher`、`createOpenMatcher` 和 `createPlainMatcher` 方法已經從 Blade 編譯器移除。在 Laravel 5.1,請使用新的 `directive` 方法來創建自定義的 Blade 標簽。請查看 [擴展 blade](/docs/{{version}}/blade#extending-blade) 文檔來了解更多信息。
### 測試
添加 protected `$baseUrl` 屬性到 `tests/TestCase.php` 文件中:
protected $baseUrl = 'http://localhost';
### 語言包
第三方擴展包發布語言包的默認目錄已經改變。必須從 `resources/lang/packages/{locale}/{namespace}` 移動所有的第三方擴展包語言包到 `resources/lang/vendor/{namespace}/{locale}` 目錄。例如,`Acme/Anvil` 擴展包命名空間為 `acme/anvil::foo` 的英文語言包應該從 `resources/lang/packages/en/acme/anvil/foo.php` 移動到 `resources/lang/vendor/acme/anvil/en/foo.php`。
### Amazon 網絡服務 SDK
如果你有使用 AWS SQS 隊列驅動或 AWS SES 電子郵件驅動,你應該升級你安裝的 AWS PHP SDK 到 3.0 版本。
如果你有使用 Amazon S3 文件系統驅動,你將需要借助 Composer 更新對應的文件系統擴展包:
- Amazon S3: `league/flysystem-aws-s3-v3 ~1.0`
### 棄用的功能
以下的 Laravel 功能已經被棄用, 并將會在 2015 十二月發布的 Laravel 5.2 中被完全移除:
<div class="content-list" markdown="1">
- 路由過濾器已經被棄用,轉而使用[中間件](/docs/{{version}}/middleware)。
- `Illuminate\Contracts\Routing\Middleware` contract 已經被棄用。你的中間件上不需要任何 contract。此外,`TerminableMiddleware` contract 也已經被棄用。不要實現接口,簡單地定義一個 `terminate` 方法在你的中間件上就好。
- `Illuminate\Contracts\Queue\ShouldBeQueued` contract 已經被棄用而用 `Illuminate\Contracts\Queue\ShouldQueue` 取代。
- Iron.io 的「推送隊列」已經被棄用而用一般的 Iron.io 隊列和[隊列監聽者](/docs/{{version}}/queues#running-the-queue-listener)取代。
- `Illuminate\Foundation\Bus\DispatchesCommands` trait 已經被棄用并改名成 `Illuminate\Foundation\Bus\DispatchesJobs`。
- `Illuminate\Container\BindingResolutionException` 被移到 `Illuminate\Contracts\Container\BindingResolutionException`。
- 服務容器的 `bindShared` 方法已經被棄用,轉而使用 `singleton` 方法取代。
- Eloquent 和查詢語句構造器的 `pluck` 方法已被棄用并改名為 `value`。
- 集合的 `fetch` 方法已經被棄用,轉而用 `pluck` 方法取代。
- `array_fetch` 輔助函數已經被棄用,轉而用 `array_pluck` 方法取代。
</div>
<a name="upgrade-5.0.16"></a>
## 升級到 5.0.16
在你的 `bootstrap/autoload.php` 文件中,更新 `$compiledPath` 變量為:
$compiledPath = __DIR__.'/../vendor/compiled.php';
<a name="upgrade-5.0"></a>
## 從 4.2 升級到 5.0
### 全新安裝,然后遷移
推薦的升級方式是創建一個全新的 Laravel `5.0` 項目,然后復制你 `4.2` 網站特定的應用程序文件到此新的應用程序。其中包含控制器、路由、Eloquent 模型、Artisan 命令、資源文件,和其它專屬于你的程序代碼。
開始前,請先在你的本地環境中 [安裝一個新的 Laravel 5 應用程序](/docs/{{version}}/installation) 到一個全新的目錄中。不要安裝超過 5.0 的任何版本,因為我們需要先完成遷移至 5.0 的步驟。我們將會在后面詳細探討各部分的詳細遷移過程。
### Composer 依賴與擴展包
別忘了復制其它額外的 Composer 依賴擴展包到你的 5.0 應用程序內。其中包含如 SDKs 的第三方代碼。
部分 Laravel 專用擴展包也許不兼容于剛發布的 Laravel 5。請向擴展包的維護者確認該擴展包支持 Laravel 5 的版本。在你添加完應用程序需要的所有額外 Composer 依賴后,請運行 `composer update`。
### 命名空間
默認情況下,Laravel 4 應用程序不會在應用程序的代碼中使用命名空間。如所有的 Eloquent 模型和控制器都簡單地存在于「全局」的命名空間中。為了更快速的遷移,Laravel 5 也允許你將這些類繼續保留在全局的命名空間內。
### 配置
#### 遷移環境變量
復制新的 `.env.example` 文件到 `.env`,在 `5.0` 中這相當于原本的 `.env.php`。在此設置合適的值,如 `APP_ENV` 和 `APP_KEY` (你的加密密鑰)、數據庫憑證、緩存驅動與 session 驅動。
此外,將你原本的 `.env.php` 文件中自定義的設置值都復制并移到 `.env` (本機環境的實際設置值) 和 `.env.example` (給其他團隊成員的范本文件)。
更多關于環境配置的信息,請查看 [完整文檔](/docs/{{version}}/installation#environment-configuration)。
> **注意:**在部署你的 Laravel 5 應用程序之前,你需要先在正式主機上放置 `.env` 文件并給其設置好適當的值。
#### 配置文件
Laravel 5.0 不再使用 `app/config/{environmentName}/` 目錄結構來為指定環境提供配置文件。取而代之的是,將環境對應的各種設置值移到 `.env`,并接著借助 `env('key', 'default value')` 來獲取配置文件的值。你可以在 `config/database.php` 配置文件中看到相關例子。
將配置文件放在 `config/` 目錄下,來代表所有環境共用的配置文件,或是在使用 `env()` 來獲取對應該環境的設置值。
請記住,如果你添加了其它的鍵值到 `.env` 文件中,記得在 `.env.example` 文件內也要添加相對應的鍵值。這將可以幫助其他團隊成員創建他們自己的 `.env` 文件。
### 路由
復制粘貼你原本的 `routes.php` 文件到 `app/Http/routes.php`。
### 控制器
下一步,將你所有的控制器移到 `app/Http/Controllers` 目錄下。因為在本指南中我們不打算遷移到完整的命名空間,請將 `app/Http/Controllers` 目錄添加到 `composer.json` 的 `classmap` 屬性中。接下來,你可以從 `app/Http/Controllers/Controller.php` 基底抽象類中移除命名空間。請確認你遷移過來的控制器都繼承這個基類。
在你的 `app/Providers/RouteServiceProvider.php` 文件,設置 `namespace` 屬性為 `null`。
### 路由過濾器
將過濾器邏輯綁定從 `app/filters.php` 復制到 `app/Providers/RouteServiceProvider.php` 的 `boot()` 方法。并在 `app/Providers/RouteServiceProvider.php` 添加 `use Illuminate\Support\Facades\Route;` 來繼續使用 `Route` Facade。
你不需要移動任何 Laravel 4.0 中的默認過濾器,如 `auth` 和 `csrf`。他們已經內置其中,只是換作以中間件形式出現。那些在路由或控制器內有使用到舊有默認過濾器的 (例如,`['before' => 'auth']`) 請修改使用新的中間件 (例如,`['middleware' => 'auth']`)。
過濾器在 Laravel 5 中沒有被移除。你仍然可以綁定并借由 `before` 和 `after` 使用你自己自定義的過濾器。
### 全局 CSRF
默認情況下,所有路由都會啟用 [CSRF 保護](/docs/{{version}}/routing#csrf-protection)。如果你想要關閉它們或是只想在特定路由手動開啟,請從 `App\Http\Kernel` 的 `middleware` 數組移除這行:
'App\Http\Middleware\VerifyCsrfToken',
如果你想要在其它地方使用它,添加此行到 `$routeMiddleware`:
'csrf' => 'App\Http\Middleware\VerifyCsrfToken',
現在你可以在路由內使用 `['middleware' => 'csrf']` 添加中間件到各個路由/控制器上。想要了解更多關于中間件的信息,請查看 [完整文檔](/docs/{{version}}/middleware)。
### Eloquent 模型
你可以隨意創建一個新的 `app/Models` 目錄來放置 Eloquent 模型。同樣地,這個目錄必須添加到 `composer.json` 文件的 `classmap` 屬性中。
將正在使用 `SoftDeletingTrait` 的模型更改為使用 `Illuminate\Database\Eloquent\SoftDeletes`。
#### Eloquent 緩存
Eloquent 不再提供 `remember` 方法來緩存查找結果。現在你有責任手動地使用 `Cache::remember` 方法緩存查找結果。要了解更多關于緩存的信息,請查看 [完整文檔](/docs/{{version}}/cache)。
### 用戶認證模型
要使用 Laravel 5 的認證系統,請遵循以下指引來升級你的 `User` 模型:
**從你的 `use` 區塊刪除以下內容:**
```php
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
```
**添加以下內容到你的 `use` 區塊:**
```php
use Illuminate\Auth\Authenticatable;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
```
**移除 UserInterface 和 RemindableInterface 接口。**
**標記類實現以下接口:**
```php
implements AuthenticatableContract, CanResetPasswordContract
```
**在類聲明引入以下 traits:**
```php
use Authenticatable, CanResetPassword;
```
**如果你有使用它們,請把 `Illuminate\Auth\Reminders\RemindableTrait` 和 `Illuminate\Auth\UserTrait` 從你的 use 區塊和類聲明中移除。**
### Cashier 的用戶需要做的修改
[Laravel Cashier](/docs/{{version}}/billing) 使用的 trait 和接口名稱已作修改。trait 請改用 `Laravel\Cashier\Billable` 取代 `BillableTrait`。接口實現請用 `Laravel\Cashier\Contracts\Billable` 取代 `Laravel\Cashier\BillableInterface`。不需要修改其它任何方法。
### Artisan 命令
將所有的命令類從原本的 `app/commands` 目錄移到新的 `app/Console/Commands` 目錄。接下來,把 `app/Console/Commands` 目錄添加到 `composer.json` 文件的 `classmap` 屬性中。
然后,把 Artisan 命令清單從 `start/artisan.php` 復制到 `app/Console/Kernel.php` 文件里的 `command` 數組中。
### 數據庫遷移和數據填充
因為數據庫里應該已經有 users 表了,請刪除 Laravel 5.0 內置的兩個遷移文件。
將所有的遷移文件從原本的 `app/database/migrations` 目錄移到新的 `database/migrations`。所有的數據填充檔也應該從 `app/database/seeds` 移到 `database/seeds`。
### 全局 IoC 綁定
如果你在 `start/global.php` 有任何的 [服務容器](/docs/{{version}}/container) 綁定,請將它們全部移至 `app/Providers/AppServiceProvider.php` 文件的 `register` 方法。你可能需要引入 `App` facade。
你也可以選擇將這些綁定,依照類拆分到各別的服務提供者中。
### 視圖
將舊視圖從 `app/views` 移到新的 `resources/views` 目錄。
### Blade 標簽修改
基于安全考量,Laravel 5.0 會把所有 `{{ }}` 和 `{{{ }}}` Blade 標簽的輸出的特殊字符都進行轉譯。新的 `{!! !!}` 標簽則被采用來顯示原始未轉譯的輸出。當你 **有足夠把握** 來保證顯示的原始輸出內容是安全的,那么升級你的應用程序的最安全方法是只使用新的 `{!! !!}` 標簽。
然而,如果你 **必須** 使用舊的 Blade 語法,請在 `AppServiceProvider@register` 的結尾加入以下幾行:
```php
\Blade::setRawTags('{{', '}}');
\Blade::setContentTags('{{{', '}}}');
\Blade::setEscapedContentTags('{{{', '}}}');
```
上述設置你不該輕易使用,這將使你的應用程序更加容易遭受 XSS 攻擊。而且用 `{{--` 注釋將無法作用。
### 語言包
將你的語言包從 `app/lang` 移到新的 `resources/lang` 目錄。
### `public` 目錄
從你的 `4.2` 應用程序的 `public` 目錄內復制公開的 assets 到新應用程序的 `public` 目錄內。請確定有保留 `5.0` 版本的 `index.php`。
### 測試
將你的測試從 `app/tests` 移到新的 `tests` 目錄。
### 雜項文件
復制項目內任何其它的文件,例如: `.scrutinizer.yml`, `bower.json` 以及其它類似的工具配置文件。
你可以將 Sass、Less 或 CoffeeScript 移動到任何你想放置的地方。`resources/assets` 目錄是一個不錯的默認位置。
### 表單和 HTML 輔助函數
如果你使用表單或 HTML 輔助函數,你將會看到 `class 'Form' not found` 或 `class 'Html' not found` 的錯誤。表單和 HTML 輔助函數已經在 Laravel 5.0 中被棄用。然而,有些社區導向的替代品可供替代,例如:[Laravel Collective](http://laravelcollective.com/docs/{{version}}/html) 維護的這些。
舉例來說,你可以把 `"laravelcollective/html": "~5.0"` 添加到你的 `composer.json` 的 `require` 區塊。
你也需要表單和 HTML 的 facades 以及服務提供者。編輯 `config/app.php` 并添加這行到 'providers' 數組內:
'Collective\Html\HtmlServiceProvider',
接著,添加這幾行到 'aliases' 數組內:
'Form' => 'Collective\Html\FormFacade',
'Html' => 'Collective\Html\HtmlFacade',
### 緩存管理員
如果你的代碼有注入 `Illuminate\Cache\CacheManager` 來獲取非 Facade 版本的 Laravel 緩存,請改成注入 `Illuminate\Contracts\Cache\Repository` 取代。
### 分頁
替換所有的 `$paginator->links()` 為 `$paginator->render()`。
依次替換所有的 `$paginator->getFrom()` 和 `$paginator->getTo()` 為 `$paginator->firstItem()` 和 `$paginator->lastItem()`。
從 `$paginator->getPerPage()`、`$paginator->getCurrentPage()`、`$paginator->getLastPage()` 和 `$paginator->getTotal()` 移除「get」前綴 (例如:`$paginator->perPage()`)。
### Beanstalk 隊列
Laravel 5.0 現在需要 `"pda/pheanstalk": "~3.0"` 取代原本的 `"pda/pheanstalk": "~2.1"`。
### Remote
Remote 組件已被棄用。
### Workbench
Workbench 組件已被棄用。
<a name="upgrade-4.2"></a>
## 從 4.1 升級到 4.2
### PHP 5.4+
Laravel 4.2 需要 PHP 5.4.0 或更高的版本。
### 默認加密
在你的 `app/config/app.php` 配置文件中添加一個新的 `cipher` 選項。這個選項的值應該為 `MCRYPT_RIJNDAEL_256`。
'cipher' => MCRYPT_RIJNDAEL_256
這個設置可以被用來調整 Laravel 加密工具使用的默認加密方法。
> **注意:**在 Laravel 4.2,默認的加密方法為 `MCRYPT_RIJNDAEL_128` (AES),它認為是最安全的加密方法。必須將加密方法改回 `MCRYPT_RIJNDAEL_256` 來解密在 Laravel 4.1 以前版本下加密的 cookies 和值。
### 現在在可以軟刪除的模型上使用 Traits
如果你有使用可以軟刪除的模型,`softDeletes` 屬性已經被移除。現在你必須使用 `SoftDeletingTrait` 如下:
use Illuminate\Database\Eloquent\SoftDeletingTrait;
class User extends Eloquent
{
use SoftDeletingTrait;
}
你也必須手動地添加 `deleted_at` 字段到你的 `dates` 屬性中:
class User extends Eloquent
{
use SoftDeletingTrait;
protected $dates = ['deleted_at'];
}
而所有軟刪除的 API 使用方式保持不變。
> **注意:**`SoftDeletingTrait` 無法在模型基類下被使用。他必須用在一個實際的模型類。
### 視圖 / 分頁的環境名稱修改
如果你直接參照 `Illuminate\View\Environment` 或 `Illuminate\Pagination\Environment` 類, 請更新你的代碼將其改為參照 `Illuminate\View\Factory` 和 `Illuminate\Pagination\Factory`。改名后的這兩個類更可以代表他們的功能。
### 額外的參數 On Pagination Presenter
如果你擴展了 `Illuminate\Pagination\Presenter` 類,抽象方法 `getPageLinkWrapper` 的參數表變成要加上 `rel` 參數:
abstract public function getPageLinkWrapper($url, $page, $rel = null);
### Iron.Io 隊列加密
如果你有使用 Iron.io 隊列驅動,你需要添加一個新的 `encrypt` 選項到你的 queue 配置文件中:
'encrypt' => true
<a name="upgrade-4.1.29"></a>
## 從 4.1.x 以前版本升級到 4.1.29
Laravel 4.1.29 對于所有的數據庫驅動加強了 column quoting 的部分。當你的模型中 **沒有** 使用 `fillable` 屬性時,他保護你的應用程序不會受到 mass assignment 漏洞影響。如果你在模型中使用 `fillable` 屬性來防范 mass assignment,你的應用程序將不會有漏洞。然而,如果你使用 `guarded` 并傳遞用戶控制的數組到「更新」或「保存」類型的函數中,那你應該立即升級到 `4.1.29` 以避免你的應用程序遭受 mass assignment 的風險。
要升級到 Laravel 4.1.29,只要 `composer update` 即可。在這個發行版本中沒有重大的更新。
<a name="upgrade-4.1.26"></a>
## 從 4.1.25 以前版本升級到 4.1.26
Laravel 4.1.26 針對「記得我」cookies 的安全性進行了更新。在此更新之前,如果一個 「記得我」cookie 被惡意用戶劫持,該 cookie 在很長一段時間內仍然有效,即便真實的用戶進行了重設密碼或者注銷等操作。
此更動需要在你的 `users` (或同等的) 數據表中添加一個額外的 `remember_token` 字段。在更新之后,當用戶每次登錄你的應用程序將會被給予一個全新的 token。在用戶注銷應用程序后,這個 token 也會被更新。這個更新的影響為:如果一個「記得我」的 cookie 被劫持,只要用戶注銷應用程序該 cookie 將會失效。
### 升級路徑
首先,添加一個新的 `remember_token` 字段到你的 `users` 數據表中,它可為空值且為 VARCHAR(100)、TEXT 或同等的類型。
然后,如果你是使用 Eloquent 認證驅動,請更新你的 `User` 類的以下三個方法:
public function getRememberToken()
{
return $this->remember_token;
}
public function setRememberToken($value)
{
$this->remember_token = $value;
}
public function getRememberTokenName()
{
return 'remember_token';
}
> **注意:**所有現存的「記得我」sessions 在此更新后將會失效,所以應用程序的所有用戶將會被迫重新認證。
### 擴展包維護者
`Illuminate\Auth\UserProviderInterface` 接口加了兩個新的方法。簡單的實現可以在默認驅動中找到:
public function retrieveByToken($identifier, $token);
public function updateRememberToken(UserInterface $user, $token);
`Illuminate\Auth\UserInterface` 也添加了三個新方法并被描述在「升級路徑」部分。
<a name="upgrade-4.1"></a>
## 從 4.0 升級到 4.1
### 升級你的 Composer 依賴
要將你的應用程序升級至 Laravel 4.1,則必須將應用程序的 `composer.json` 里的 `laravel/framework` 版本更改至 `4.1.*`。
### 文件替換
將你的 `public/index.php` 文件替換為 [這個從 repository 復制的全新文件](https://github.com/laravel/laravel/blob/v4.1.0/public/index.php)。
將你的 `artisan` 文件替換為 [這個從 repository 復制的全新文件](https://github.com/laravel/laravel/blob/v4.1.0/artisan)。
### 添加配置文件及選項
更新 `app/config/app.php` 配置文件里的 `aliases` 和 `providers` 數組。這些數組更新后的值可以在 [這個文件](https://github.com/laravel/laravel/blob/v4.1.0/app/config/app.php)中找到。請確保你自定義的 providers / aliases 和擴展包的 providers / aliases 都已添加回數組中。
[從 repository](https://github.com/laravel/laravel/blob/v4.1.0/app/config/remote.php) 添加新的 `app/config/remote.php` 文件。
在你的 `app/config/session.php` 文件里,添加新的 `expire_on_close` 設置選項。默認值應該為 `false`。
在你的 `app/config/queue.php` 文件里,添加新的 `failed` 設置區塊。以下為這區塊的默認值:
'failed' => [
'database' => 'mysql', 'table' => 'failed_jobs',
],
**(可選的)** 在你的 `app/config/view.php` 文件里,將 `pagination` 設置選項更新為 `pagination::slider-3`。
### 控制器的修改
如果 `app/controllers/BaseController.php` 有個 `use` 語句在最上面,將 `use Illuminate\Routing\Controllers\Controller;` 改為 `use Illuminate\Routing\Controller;`。
### 密碼提醒的修改
密碼提醒功能在大幅改進后已經具有更好的靈活性。你可以運行 `php artisan auth:reminders-controller` Artisan 命令來檢查新的存根控制器。你也可以瀏覽 [更新后的文檔](/docs/security#password-reminders-and-reset) 來相應更新你的應用程序。
更新你的 `app/lang/en/reminders.php` 語言文件來對應 [這個新版文件](https://github.com/laravel/laravel/blob/v4.1.0/app/lang/en/reminders.php)。
### 環境偵測的修改
為了安全因素,不再使用網址域名來偵測應用程序的環境。因為這些值很容易被偽造欺騙,繼而讓攻擊者通過請求來修改環境。你必須改為使用機器的主機名稱 (在 Mac、Linux 和 Windows 下運行 `hostname` 命令的值) 來偵測環境。
### 更簡單的日志文件
Laravel 目前只會生成單個的日志文件:`app/storage/logs/laravel.log`。然而,你還是可以在 `app/start/global.php` 文件設置更改它的行為。
### 移除重定向向結尾的斜線
在你的 `bootstrap/start.php` 文件中,移除對 `$app->redirectIfTrailingSlash()` 的調用。這個方法已經不再需要,因為這個功能現在已交由框架內的 `.htaccess` 文件來處理。
然后,用 [新的文件](https://github.com/laravel/laravel/blob/v4.1.0/public/.htaccess) 替換為 Apache 的 `.htaccess`,來處理結尾的斜線。
### 獲取目前路由
現在通過 `Route::current()` 獲取當前路由,而不是 `Route::getCurrentRoute()`。
### Composer 更新
一旦你完成以上更新,則可以運行 `composer update` 功能來更新應用程序的核心文件!如果發生 class load 錯誤,試著運行 `update` 命令并加上 `--no-scripts` 選項,樣就像這樣:`composer update --no-scripts`。
### 通配符事件監聽者
通配符事件監聽者不再添加事件到你的處理函數參數上。如果你需要尋找觸發的事件,則可用 `Event::firing()` 來觸發。
- 說明
- 翻譯說明
- 發行說明
- 升級說明
- 貢獻導引
- 入門指南
- 安裝
- 配置信息
- 文件夾結構
- 錯誤與日志
- 開發環境
- HomeStead
- Valet
- 核心概念
- 服務容器
- 服務提供者
- 門面(facades)
- contracts
- HTTP層
- 路由
- 中間件
- CSRF保護
- 控制器
- 請求
- 響應
- Session
- 表單驗證
- 視圖與模板
- 視圖
- Blade模板
- 本地化
- Javascript與CSS
- 入門指南
- laravel-elixir
- 安全
- 用戶認證
- 用戶授權
- 重置密碼
- API授權
- 加密解密
- 哈希
- 綜合話題
- 廣播系統
- 緩存系統
- 事件系統
- 文件存儲
- 郵件發送
- 消息通知
- 隊列
- 數據庫
- 快速入門
- 查詢構造器
- 分頁
- 數據庫遷移
- 數據填充
- redis
- Eloquent ORM
- 快速入門
- 模型關聯
- Eloquent集合
- 修改器
- 序列化
- Artisan控制臺
- Artisan 命令行
- 任務調度
- 測試
- 快速入門
- 應用程序測試
- 數據庫測試
- 模擬器
- 官方擴展包
- Cashier交易包
- Envoy 部署工具
- Passport OAuth 認證
- Scout 全文搜索
- Socialite 社交化登錄
- 附錄
- 集合
- 輔助函數
- 擴展包開發
- 交流說明