Skip to content

升級指南

高影響變更

中影響變更

低影響變更

從 10.x 升級到 11.0

預估升級時間:15 分鐘

📌 備註

我們會盡力記錄所有可能導致破壞性變更的內容。由於其中一些破壞性變更發生於框架中較不常見的部分,因此這些變更可能只會影響您的應用程式一小部分。想節省時間嗎?您可以使用 Laravel Shift 來自動化應用程式的升級。

更新依賴套件

影響可能性:高

必備 PHP 8.2.0

Laravel 現在需要 PHP 8.2.0 或更高版本。

必備 curl 7.34.0

Laravel 的 HTTP Client 現在需要 curl 7.34.0 或更高版本。

Composer 依賴套件

您應更新應用程式 composer.json 檔案中的下列依賴套件:

  • laravel/framework to ^11.0
  • nunomaduro/collision to ^8.1
  • laravel/breeze to ^2.0 (如果已安裝)
  • laravel/cashier to ^15.0 (如果已安裝)
  • laravel/dusk to ^8.0 (如果已安裝)
  • laravel/jetstream to ^5.0 (如果已安裝)
  • laravel/octane to ^2.3 (如果已安裝)
  • laravel/passport to ^12.0 (如果已安裝)
  • laravel/sanctum to ^4.0 (如果已安裝)
  • laravel/scout to ^10.0 (如果已安裝)
  • laravel/spark-stripe to ^5.0 (如果已安裝)
  • laravel/telescope to ^5.0 (如果已安裝)
  • livewire/livewire to ^3.4 (如果已安裝)
  • inertiajs/inertia-laravel to ^1.0 (如果已安裝)

如果您的應用程式正在使用 Laravel Cashier Stripe, Passport, Sanctum, Spark Stripe, 或 Telescope,您將需要將它們的遷移檔案發布到您的應用程式。Cashier Stripe, Passport, Sanctum, Spark Stripe, 及 Telescope 不再自動從其自身的遷移檔案目錄中載入遷移。因此,您應該執行以下命令將它們的遷移檔案發布到您的應用程式:

bash
php artisan vendor:publish --tag=cashier-migrations
php artisan vendor:publish --tag=passport-migrations
php artisan vendor:publish --tag=sanctum-migrations
php artisan vendor:publish --tag=spark-migrations
php artisan vendor:publish --tag=telescope-migrations

此外,您應該審閱每個套件的升級指南,以確保您了解任何額外的破壞性變更:

如果您已手動安裝 Laravel installer,您應該透過 Composer 更新 installer:

bash
composer global require laravel/installer:^5.6

最後,如果您先前已將 doctrine/dbal Composer 依賴套件添加到您的應用程式中,則可以將其移除,因為 Laravel 不再依賴此套件。

應用程式結構

Laravel 11 引入了一個新的預設應用程式結構,其預設檔案較少。也就是說,新的 Laravel 應用程式包含較少的 Service Provider、中介層 (middleware) 和組態檔 (configuration files)。

然而,我們不建議從 Laravel 10 升級到 Laravel 11 的應用程式嘗試遷移其應用程式結構,因為 Laravel 11 已經過精心調整,以同時支援 Laravel 10 的應用程式結構。

認證

密碼重新雜湊

影響可能性:低

如果您的雜湊演算法 (hashing algorithm) 的「工作因子 (work factor)」自上次雜湊密碼後已更新,Laravel 11 將在認證期間自動重新雜湊您使用者的密碼。

通常,這不會中斷您的應用程式;但是,如果您的 User 模型的「password」欄位名稱不是 password,您應該透過模型的 authPasswordName 屬性指定該欄位的名稱:

protected $authPasswordName = 'custom_password_field';

或者,您可以透過在應用程式的 config/hashing.php 組態檔中添加 rehash_on_login 選項來禁用密碼重新雜湊:

'rehash_on_login' => false,

UserProvider 契約

影響可能性:低

Illuminate\Contracts\Auth\UserProvider 契約已收到一個新的 rehashPasswordIfRequired 方法。當應用程式的雜湊演算法工作因子發生變更時,此方法負責重新雜湊並將使用者的密碼儲存在儲存空間中。

如果您的應用程式或套件定義了一個實作此介面的類別,您應該將新的 rehashPasswordIfRequired 方法添加到您的實作中。參考實作可以在 Illuminate\Auth\EloquentUserProvider 類別中找到:

php
public function rehashPasswordIfRequired(Authenticatable $user, array $credentials, bool $force = false);

Authenticatable 契約

影響可能性:低

Illuminate\Contracts\Auth\Authenticatable 契約已收到一個新的 getAuthPasswordName 方法。此方法負責返回您的可認證實體 (authenticatable entity) 的密碼欄位名稱。

如果您的應用程式或套件定義了一個實作此介面的類別,您應該將新的 getAuthPasswordName 方法添加到您的實作中:

php
public function getAuthPasswordName()
{
    return 'password';
}

Laravel 附帶的預設 User 模型會自動接收此方法,因為該方法包含在 Illuminate\Auth\Authenticatable Trait 中。

AuthenticationException 類別

影響可能性:非常低

Illuminate\Auth\AuthenticationException 類別的 redirectTo 方法現在需要一個 Illuminate\Http\Request 實例作為其第一個參數。如果您手動捕捉此例外並呼叫 redirectTo 方法,您應該相應地更新您的程式碼:

php
if ($e instanceof AuthenticationException) {
    $path = $e->redirectTo($request);
}

註冊時的 Email 驗證通知

影響可能性:非常低

如果 Registered 事件尚未由您的應用程式的 EventServiceProvider 註冊,SendEmailVerificationNotification 監聽器現在會自動為其註冊。如果您的應用程式的 EventServiceProvider 沒有註冊此監聽器,並且您不希望 Laravel 自動為您註冊,您應該在應用程式的 EventServiceProvider 中定義一個空的 configureEmailVerification 方法:

php
protected function configureEmailVerification()
{
    // ...
}

快取

快取鍵前綴

影響可能性:非常低

之前,如果為 DynamoDB、Memcached 或 Redis 快取儲存定義了快取鍵前綴,Laravel 會在該前綴後附加一個 :。在 Laravel 11 中,快取鍵前綴不會收到 : 後綴。如果您想保持之前的前綴行為,您可以手動在您的快取鍵前綴中添加 : 後綴。

集合 (Collections)

Enumerable 契約

影響可能性:低

Illuminate\Support\Enumerable 契約的 dump 方法已更新為接受一個變數參數 ...$args。如果您正在實作此介面,您應該相應地更新您的實作:

php
public function dump(...$args);

資料庫

SQLite 3.26.0+

影響可能性:高

如果您的應用程式使用 SQLite 資料庫,則需要 SQLite 3.26.0 或更高版本。

Eloquent Model casts 方法

影響可能性:低

基礎 Eloquent 模型類別現在定義了一個 casts 方法,以支援屬性型別轉換的定義。如果您的應用程式的其中一個模型定義了 casts 關聯,它可能會與基礎 Eloquent 模型類別中現在存在的 casts 方法衝突。

修改欄位

影響可能性:高

修改欄位時,您現在必須明確包含變更後希望保留在欄位定義上的所有修飾符。任何遺失的屬性都將被捨棄。例如,為了保留 unsigneddefaultcomment 屬性,即使這些屬性已經由先前的 migration 分配給欄位,您也必須在變更欄位時明確呼叫每個修飾符。

例如,假設您有一個 migration 創建了一個 votes 欄位,並帶有 unsigneddefaultcomment 屬性:

php
Schema::create('users', function (Blueprint $table) {
    $table->integer('votes')->unsigned()->default(1)->comment('The vote count');
});

之後,您編寫了一個 migration,也將該欄位變更為 nullable

php
Schema::table('users', function (Blueprint $table) {
    $table->integer('votes')->nullable()->change();
});

在 Laravel 10 中,這個 migration 會保留欄位的 unsigneddefaultcomment 屬性。然而,在 Laravel 11 中,migration 現在還必須包含所有先前在欄位上定義的屬性。否則,它們將被捨棄:

php
Schema::table('users', function (Blueprint $table) {
    $table->integer('votes')
        ->unsigned()
        ->default(1)
        ->comment('The vote count')
        ->nullable()
        ->change();
});

change 方法不會變更欄位的索引。因此,您可以在修改欄位時使用索引修飾符來明確添加或捨棄索引:

php
// Add an index...
$table->bigIncrements('id')->primary()->change();

// Drop an index...
$table->char('postal_code', 10)->unique(false)->change();

如果您不想更新應用程式中所有現有的「變更」migrations 來保留欄位的現有屬性,您可以直接 壓縮您的 migrations

bash
php artisan schema:dump

一旦您的 migrations 被壓縮,Laravel 將在執行任何待處理的 migrations 之前,使用您應用程式的 schema 檔案來「遷移」資料庫。

浮點數型別

影響可能性:高

doublefloat migration 欄位型別已重新編寫,以便在所有資料庫中保持一致。

double 欄位型別現在會建立一個與 DOUBLE 等效的欄位,不包含總位數和小數位數(小數點後的位數),這是標準的 SQL 語法。因此,您可以移除 $total$places 的參數:

php
$table->double('amount');

float 欄位型別現在會建立一個與 FLOAT 等效的欄位,不包含總位數和小數位數(小數點後的位數),但帶有可選的 $precision 規範,以決定儲存大小為 4-byte 單精度欄位或 8-byte 雙精度欄位。因此,您可以移除 $total$places 的參數,並根據您的資料庫文件將可選的 $precision 指定為您所需的值:

php
$table->float('amount', precision: 53);

unsignedDecimalunsignedDoubleunsignedFloat 方法已被移除,因為這些欄位型別的 unsigned 修飾符已被 MySQL 棄用,並且從未在其他資料庫系統中標準化。然而,如果您希望繼續使用這些欄位型別的已棄用 unsigned 屬性,您可以將 unsigned 方法鏈接到欄位的定義中:

php
$table->decimal('amount', total: 8, places: 2)->unsigned();
$table->double('amount')->unsigned();
$table->float('amount', precision: 53)->unsigned();

專用 MariaDB 驅動程式

影響可能性:非常低

Laravel 11 增加了專用於 MariaDB 的資料庫驅動程式,而非在連接 MariaDB 資料庫時總是使用 MySQL 驅動程式。

如果您的應用程式連接到 MariaDB 資料庫,您可以將連線設定更新為新的 mariadb 驅動程式,以便在未來受益於 MariaDB 特有的功能:

'driver' => 'mariadb',
'url' => env('DB_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
// ...

目前,新的 MariaDB 驅動程式行為與目前的 MySQL 驅動程式相似,但有一個例外:uuid schema builder 方法會建立原生的 UUID 欄位,而不是 char(36) 欄位。

如果您現有的 migrations 使用 uuid schema builder 方法,並且您選擇使用新的 mariadb 資料庫驅動程式,您應該將 migration 中對 uuid 方法的呼叫更新為 char,以避免破壞性變更或意外行為:

php
Schema::table('users', function (Blueprint $table) {
    $table->char('uuid', 36);

    // ...
});

空間型別

影響可能性:低

資料庫 migrations 中的空間欄位型別已重新編寫,以便在所有資料庫中保持一致。因此,您可以從您的 migrations 中移除 pointlineStringpolygongeometryCollectionmultiPointmultiLineStringmultiPolygonmultiPolygonZ 方法,改為使用 geometrygeography 方法:

php
$table->geometry('shapes');
$table->geography('coordinates');

若要明確限制 MySQL、MariaDB 和 PostgreSQL 上欄位中儲存值的型別或空間參考系統識別符,您可以將 subtypesrid 傳遞給該方法:

php
$table->geometry('dimension', subtype: 'polygon', srid: 0);
$table->geography('latitude', subtype: 'point', srid: 4326);

PostgreSQL 語法中的 isGeometryprojection 欄位修飾符已相應移除。

移除 Doctrine DBAL

影響可能性:低

以下列出的 Doctrine DBAL 相關類別和方法已被移除。Laravel 不再依賴此套件,並且不再需要註冊自訂的 Doctrines 型別,即可正確建立和修改先前需要自訂型別的各種欄位型別:

  • Illuminate\Database\Schema\Builder::$alwaysUsesNativeSchemaOperationsIfPossible class property
  • Illuminate\Database\Schema\Builder::useNativeSchemaOperationsIfPossible() method
  • Illuminate\Database\Connection::usingNativeSchemaOperations() method
  • Illuminate\Database\Connection::isDoctrineAvailable() method
  • Illuminate\Database\Connection::getDoctrineConnection() method
  • Illuminate\Database\Connection::getDoctrineSchemaManager() method
  • Illuminate\Database\Connection::getDoctrineColumn() method
  • Illuminate\Database\Connection::registerDoctrineType() method
  • Illuminate\Database\DatabaseManager::registerDoctrineType() method
  • Illuminate\Database\PDO directory
  • Illuminate\Database\DBAL\TimestampType class
  • Illuminate\Database\Schema\Grammars\ChangeColumn class
  • Illuminate\Database\Schema\Grammars\RenameColumn class
  • Illuminate\Database\Schema\Grammars\Grammar::getDoctrineTableDiff() method

此外,不再需要在應用程式的 database 設定檔中透過 dbal.types 註冊自訂 Doctrine 型別。

如果您之前使用 Doctrine DBAL 來檢查您的資料庫及其相關表格,您可以改用 Laravel 新的原生 schema 方法(Schema::getTables()Schema::getColumns()Schema::getIndexes()Schema::getForeignKeys() 等)。

已棄用的 Schema 方法

影響可能性:非常低

已棄用、基於 Doctrine 的 Schema::getAllTables()Schema::getAllViews()Schema::getAllTypes() 方法已被移除,改為使用新的 Laravel 原生 Schema::getTables()Schema::getViews()Schema::getTypes() 方法。

當使用 PostgreSQL 和 SQL Server 時,所有新的 schema 方法都不會接受三段式參考(例如 database.schema.table)。因此,您應該改用 connection() 來宣告資料庫:

php
Schema::connection('database')->hasTable('schema.table');

Schema Builder getColumnType() 方法

影響可能性:非常低

Schema::getColumnType() 方法現在總是回傳給定欄位的實際型別,而不是 Doctrine DBAL 等效型別。

資料庫連線介面

影響可能性:非常低

Illuminate\Database\ConnectionInterface 介面已新增一個 scalar 方法。如果您正在定義自己的此介面實作,您應該將 scalar 方法新增到您的實作中:

php
public function scalar($query, $bindings = [], $useReadPdo = true);

日期

Carbon 3

影響可能性: 中

Laravel 11 同時支援 Carbon 2 和 Carbon 3。Carbon 是被 Laravel 和整個生態系統中的套件廣泛使用的日期操作函式庫。如果您升級到 Carbon 3,請注意 diffIn* 方法現在會回傳浮點數,並且可能會回傳負值以表示時間方向,這與 Carbon 2 有顯著差異。請查閱 Carbon 的 變更日誌文件 以獲取有關如何處理這些及其他變更的詳細資訊。

郵件

Mailer 契約

影響可能性: 極低

Illuminate\Contracts\Mail\Mailer 契約已新增了一個 sendNow 方法。如果您的應用程式或套件手動實作此契約,您應該將新的 sendNow 方法新增到您的實作中:

php
public function sendNow($mailable, array $data = [], $callback = null);

套件

將 Service Providers 發佈到應用程式

影響可能性: 極低

如果您編寫了一個 Laravel 套件,該套件手動將 Service Provider 發佈到應用程式的 app/Providers 目錄,並手動修改應用程式的 config/app.php 配置檔以註冊該 Service Provider,您應該更新您的套件以使用新的 ServiceProvider::addProviderToBootstrapFile 方法。

addProviderToBootstrapFile 方法會自動將您已發佈的 Service Provider 加入到應用程式的 bootstrap/providers.php 檔案中,因為在新的 Laravel 11 應用程式中,providers 陣列不存在於 config/app.php 配置檔中。

php
use Illuminate\Support\ServiceProvider;

ServiceProvider::addProviderToBootstrapFile(Provider::class);

佇列

BatchRepository 介面

影響可能性: 極低

Illuminate\Bus\BatchRepository 介面已新增了一個 rollBack 方法。如果您在自己的套件或應用程式中實作此介面,您應該將此方法新增到您的實作中:

php
public function rollBack();

資料庫交易中的同步化 Job

影響可能性: 極低

以前,同步化 Job (使用 sync 佇列驅動程式的 Job) 會立即執行,無論佇列連線的 after_commit 配置選項是否設定為 true,或 afterCommit 方法是否在 Job 上被呼叫。

在 Laravel 11 中,同步化佇列 Job 現在將遵循佇列連線或 Job 的「after commit」配置。

速率限制

每秒速率限制

影響可能性: 中

Laravel 11 支援每秒速率限制,而不再限於每分鐘的粒度。關於這項變更,您應該注意各種潛在的破壞性變更。

GlobalLimit 類別的建構函式現在接受秒數而不是分鐘數。此類別並未被文件說明,通常不會被您的應用程式使用:

php
new GlobalLimit($attempts, 2 * 60);

Limit 類別的建構函式現在接受秒數而不是分鐘數。此類別的所有文件說明的使用方式都限於靜態建構函式,例如 Limit::perMinuteLimit::perSecond。但是,如果您手動實例化此類別,則應更新您的應用程式,向類別的建構函式提供秒數:

php
new Limit($key, $attempts, 2 * 60);

Limit 類別的 decayMinutes 屬性已更名為 decaySeconds,現在包含秒數而不是分鐘數。

Illuminate\Queue\Middleware\ThrottlesExceptionsIlluminate\Queue\Middleware\ThrottlesExceptionsWithRedis 類別的建構函式現在接受秒數而不是分鐘數:

php
new ThrottlesExceptions($attempts, 2 * 60);
new ThrottlesExceptionsWithRedis($attempts, 2 * 60);

Cashier Stripe

更新 Cashier Stripe

影響可能性: 高

Laravel 11 不再支援 Cashier Stripe 14.x。因此,您應該在應用程式的 composer.json 檔案中,將 Laravel Cashier Stripe 的依賴更新為 ^15.0

Cashier Stripe 15.0 不再自動從其本身的遷移目錄載入遷移。相反地,您應該執行以下指令將 Cashier Stripe 的遷移發佈到您的應用程式:

shell
php artisan vendor:publish --tag=cashier-migrations

請查閱完整的 Cashier Stripe 升級指南 以了解其他破壞性變更。

Spark (Stripe)

更新 Spark Stripe

影響可能性: 高

Laravel 11 不再支援 Laravel Spark Stripe 4.x。因此,您應該在應用程式的 composer.json 檔案中,將 Laravel Spark Stripe 的依賴更新為 ^5.0

Spark Stripe 5.0 不再自動從其本身的遷移目錄載入遷移。相反地,您應該執行以下指令將 Spark Stripe 的遷移發佈到您的應用程式:

shell
php artisan vendor:publish --tag=spark-migrations

請查閱完整的 Spark Stripe 升級指南 以了解其他破壞性變更。

Passport

更新 Passport

影響可能性: 高

Laravel 11 不再支援 Laravel Passport 11.x。因此,您應該在應用程式的 composer.json 檔案中,將 Laravel Passport 的依賴更新為 ^12.0

Passport 12.0 不再自動從其本身的遷移目錄載入遷移。相反地,您應該執行以下指令將 Passport 的遷移發佈到您的應用程式:

shell
php artisan vendor:publish --tag=passport-migrations

此外,密碼授權類型預設為禁用。您可以透過在應用程式的 AppServiceProviderboot 方法中呼叫 enablePasswordGrant 方法來啟用它:

public function boot(): void
{
    Passport::enablePasswordGrant();
}

Sanctum

更新 Sanctum

影響可能性: 高

Laravel 11 不再支援 Laravel Sanctum 3.x。因此,您應該在應用程式的 composer.json 檔案中,將 Laravel Sanctum 的依賴更新為 ^4.0

Sanctum 4.0 不再自動從其本身的遷移目錄載入遷移。相反地,您應該執行以下指令將 Sanctum 的遷移發佈到您的應用程式:

shell
php artisan vendor:publish --tag=sanctum-migrations

然後,在您的應用程式的 config/sanctum.php 配置檔中,您應該將對 authenticate_sessionencrypt_cookiesvalidate_csrf_token 中介層的引用更新為以下內容:

'middleware' => [
    'authenticate_session' => Laravel\Sanctum\Http\Middleware\AuthenticateSession::class,
    'encrypt_cookies' => Illuminate\Cookie\Middleware\EncryptCookies::class,
    'validate_csrf_token' => Illuminate\Foundation\Http\Middleware\ValidateCsrfToken::class,
],

Telescope

更新 Telescope

影響可能性:高

Laravel 11 不再支援 Laravel Telescope 4.x。因此,您應該在應用程式的 composer.json 檔案中,將 Laravel Telescope 依賴套件更新到 ^5.0

Telescope 5.0 不再自動從其本身的 migrations 目錄載入 migrations。您應該執行以下指令,將 Telescope 的 migrations 發佈到您的應用程式:

shell
php artisan vendor:publish --tag=telescope-migrations

Spatie Once 套件

影響可能性:中

Laravel 11 現在提供了自己的 once 函式,以確保給定的閉包只會執行一次。因此,如果您的應用程式依賴於 spatie/once 套件,您應該從應用程式的 composer.json 檔案中移除它,以避免衝突。

雜項

我們也鼓勵您查看 laravel/laravel GitHub 儲存庫中的變更。儘管其中許多變更不是必需的,但您可能會希望讓這些檔案與您的應用程式保持同步。本升級指南將涵蓋其中一些變更,但其他變更,例如設定檔或註解的變更,則不會涵蓋。您可以輕鬆地使用 GitHub 比較工具 來查看這些變更,並選擇對您而言重要的更新。