展開文件目錄

升級指南

從 5.6 升級到 5.6.30(安全性更新版本)

Laravel 5.6.30 是 Laravel 安全性更新版本,建議所有使用者即刻升級。Laravel 5.6.30 也有對 Cookie 加密與序列化邏輯的重大變更,所以在升級應用程式前請詳閱以下說明。

這個漏洞只會在惡意使用者持有了你的應用程式的加密金鑰(APP_KEY 環境變數)時發生。一般情況下,你的使用者是不可能存取到這個值。然而,有權限存取加密金鑰的前員工就有機會使用這個金鑰來攻擊你的應用程式。如果你有任何理由來讓你相信自身的加密金鑰已落入不肖人士手裡,則一定要翻新這個金鑰的值。

Cookie 序列化

Laravel 5.6.30 已經停用所有 Cookie 值的序列化與反序列化。由於所有 Laravel Cookie 都有被加密與簽章的,所以理論上 Cookie 的值是可以防止客戶端的竄改的。然而,如果你的應用程式的加密金鑰落入不肖人士手中,則他們可以使用該加密金鑰來製作 Cookie 值,並利用 PHP 物件的序列化與反序列化的既有漏洞,像是在應用程式內呼叫任意類別的方法。

停用所有 Cookie 值的序列化會使你的應用程式的所有 Session 無效,以及所有使用者會需要再次登入應用程式(如果他們有用到 remember_token,這時使用者會自動被登入)。還有,你的應用程式當時正在加密 Cookie 任何值都會無效喔。也因為這樣,你可能希望加入額外的邏輯到應用程式來驗證自訂的 Cookie 值是否與預期的值清單相符;如果沒有相符,你應該捨棄他們。

設定 Cookie 序列化

因為無法存取你應用程式的加密金鑰,所以這個漏洞無法被使用。我們選擇了一種做法來提供你在重新啟用加密的 Cookie 序列化時也能讓應用程式相容這些變更。要啟用與停用 Cookie 序列化,可以更改 App\Http\Middleware\EncryptCookies 中介層serialize 靜態屬性:

/**
 * 是否要序列化 Cookie。
 *
 * @var bool
 */
protected static $serialize = true;

注意: 當你啟用加密的 Cookie 序列化後,若應用程式的加密金鑰落入不肖人士手中,就容易遭受攻擊。如果你認為你的金鑰落入不肖人士手中,你應該在啟用加密 Cookie 序列化之前翻新金鑰的值。

Dusk 4.0.0

已發布 Dusk 4.0.0,且不會序列化 Cookie。如果你選擇啟用 Cookie 序列化,你應該繼續使用 Dusk 3.0.0。不然,你應該升級到 4.0.0。

Passport 6.0.7

已發布 Passport 6.0.7,並加入 Laravel\Passport\Passport::withoutCookieSerialization() 新方法。在你停用 Cookie 序列化後,你可以在應用程式的 AppServiceProvider 中呼叫這個方法。

從 5.5 升級到 5.6.0

預估升級時間:10 - 30 分鐘

{note} 我們嘗試記錄每個重大變更。由於有些重大的變更是在框架最隱密的地方,但實際上只有一小部分的變更會影響你的應用程式。

PHP

Laravel 5.6 需要 PHP 7.1.3 或更高的版本。

更新依賴項目

composer.json 檔案中更新 laravel/framework5.6.* 還有 fideloper/proxy 更新到 ^4.0

如果你有使用 laravel/browser-kit-testing 套件,則要在 composer.json 更新該套件到 4.*

還有,如果你有使用第三方的 Laravel 套件,你應該升級他們到他們最後發布的版本:

  • Dusk(升級到 ^3.0
  • Passport(升級到 ^6.0
  • Scout(升級到 ^4.0

最後,請檢查你的應用程式所使用的第三方套件的版本是否能支援 Laravel 5.6。

Symfony 4

Laravel 所使用的底層 Symfony 元件都已升級到 ^4.0 發布的版本。如果你有在應用程式中直接使用 Symfony 元件,請你先看 Symfony 更新記錄

PHPUnit

你應該升級 phpunit/phpunit^7.0

陣列

Arr::wrap 方法

現在傳入 nullArr::warp 方法會回傳一組空陣列。

Artisan

optimize 命令

之前棄用的 optimize Artisan 命令已被移除。隨著近年來 PHP 自身的 OPcache 的改良,optimize 命令不再提供任何相關的性能優化。因此,你可以從 composer.json 檔案移除 scripts 中的 php artisan optimize

Blade

HTML 實體編碼

在之前的 Laravel 版本中,Blade(與 e 輔助函式)不會對 HTML 實體進行二次編碼。這並不是底層 htmlspecialchars 底層預設的用法,且 在渲染內容或直接傳遞 JSON 內容到 JaveScript 框架時可能會導致意外發生。

在 Laravel 5.6,Blade 與 e 輔助函式預設會對特殊字元做二次編碼。讓這些功能與預設 PHP 底層的 htmlspecialchars 函式的用法保持一致性。如果你想要維持過去防止防止二次編碼的用法,可以使用 Blade::withoutDoubleEncoding

<?php

namespace App\Providers;

use Illuminate\Support\Facades\Blade;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * 啟動任何應用程式服務。
     *
     * @return void
     */
    public function boot()
    {
        Blade::withoutDoubleEncoding();
    }
}

快取

限制使用率 tooManyAttempts 方法

已經從這個方法中移除未被使用 $decayMinutes 參數。如果你有自己的實例覆寫過這個方法,也請從這個方法中刪除該參數。

資料庫

多型欄位的索引排序

為了提高性能,將對調建構 morphs 遷移方法的欄位索引。如果你有在 Migrate 中用過 morphs 方法,則會在執行 Migrate 的 down 方法時收到錯誤訊息。如果應用程式還在開發階段,你可以使用 migrate:fresh 命令來重頭開始重建資料庫。如果應用程式已正式上線,則要把索引名稱傳遞給 morphs 方法。

新增 MigrationRepositoryInterface 方法

新的 getMigrationsBatches 方法已新增到 MigrationRepositoryInterface。你可能在極少數的情況下會定義這個類別到自己的實例上,請將這個方法加到你的實例中。你能以框架為例來查看預設的實例。

Eloquent

getDateFormat 方法

getDateFormat 方法現在是 public,而不是 protected

雜湊化

新的設定檔

現在所有的雜湊設定都放在 config/hashing.php 設定檔。你可以在自己的應用程式放置預設設定檔的副本。你想必會將 bcrypt 驅動繼續做為預設的驅動。不過,也有支援 argon

輔助函式

e 輔助方法

在之前的 Laravel 版本中,Blade(與 e 輔助函式)不會對 HTML 實體進行二次編碼。這並不是底層 htmlspecialchars 底層預設的用法,且 在渲染內容或直接傳遞 JSON 內容到 JaveScript 框架時可能會導致意外發生。

在 Laravel 5.6,Blade 與 e 輔助函式預設會對特殊字元做二次編碼。讓這些功能與預設 PHP 底層的 htmlspecialchars 函式的用法保持一致性。果你想要維持過去防止防止二次編碼的用法,可以傳入 falsee 輔助函式的第二個參數:

<?php echo e($string, false); ?>

日誌系統

新的設定檔

現在所有日誌設定全都放置在 config/logging.php 設定檔。你可以在自己的應用程式放置預設設定檔的副本,並依據應用程式的需求來調整設定。

可以從 config/app.php 設定檔中刪除 loglog_level 設定選項。

configureMonologUsing 方法

如果你有用到 configureMonologUsing 方法來為你的應用程式客製化 Monolog 實例。你現在能建立 custom 日誌頻道。更多關於如何建立自訂頻道,請詳閱完整日誌文件

日誌 Writer 類別

Illuminate\Log\Writer 類別已重新命名為 Illuminate\Log\Logger。如果你有使用這個類別作為應用程式的依賴項目之一,應該更新該類別到新名字。或者,你可以考慮使用標準化的 Psr\Log\LoggerInterface 來取代之。

Illuminate\Contracts\Logging\Log 介面

由於這個介面完全重複 Psr\Log\LoggerInterface 介面,所以已移除這個介面。你應該使用 Psr\Log\LoggerInterface 介面來取代。

郵件

withSwiftMessage 回呼

在 Laravel 之前的版本,在內容準備好編碼並加到訊息之後,才使用 withSwiftMessage 來註冊 Swift 訊息客製化回呼。現在這些回呼會在內容被加入_之前_呼叫,這能讓你根據需求來客製化編碼或其他訊息選項。

分頁

Bootstrap 4

現在分頁器產生的分頁連結預設會是 Bootstrap 4。要讓分頁器產生 Bootstrap 3 連結,可以從 AppServiceProviderboot 方法呼叫 Paginator::useBootstrapThree 方法:

<?php

namespace App\Providers;

use Illuminate\Pagination\Paginator;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * 啟動任何應用程式服務。
     *
     * @return void
     */
    public function boot()
    {
        Paginator::useBootstrapThree();
    }
}

Resources

original 屬性

resource 回應original 屬性現在設為原生模型,而不是 JSON 字串與陣列。這可以在測試過程中更容易的檢查回應的模型。

路由

回傳新建立的模型時

直接從路由回傳新建立的 Eloquent 模型會自動回應 201 的狀態,而不是 200。如果你的應用程式的任何測試有預期回應 200,則應該更新這些測試預期為 201

可信任的代理

因為 Symfony HttpFoundation 的可信任代理功能的底層有更動,所以必須修改你的應用程式的中介層。

$headers 屬性在過去是一組陣列,現在則是一個 bit 屬性,可以接受不同的值。例如,要信任所有轉發的標頭,你可以把 $headers 屬性更新為下列的值:

use Illuminate\Http\Request;

/**
 * 被用於檢查代理的標頭。
 *
 * @var int
 */
protected $headers = Request::HEADER_X_FORWARDED_ALL;

更多關於 $headers 值的資訊,請詳閱信任代理上的所有文件。

驗證

ValidatesWhenResolved 介面

為了避免與 $request->validate() 方法衝突,已將 ValidatesWhenResolved interface/trait 重新命名為 validateResolved

其他

我們也鼓勵你查看 laravel/laravel GitHub repository GitHub 儲存庫中的任何異動。儘管許多更改並不是必要的,但你可能希望保持這些文件與你的應用程序同步。其中一些更改將在本升級指南中介紹,但其他更改(例如更改設定檔案或註釋)將不會被介紹。你可以使用 GitHub 比較工具來輕易的檢查更動的內容,並選擇哪些更新對你比較重要。