升級指南
高影響變更
中影響變更
低影響變更
從 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 不再自動從其自身的遷移檔案目錄中載入遷移。因此,您應該執行以下命令將它們的遷移檔案發布到您的應用程式:
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:
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
類別中找到:
public function rehashPasswordIfRequired(Authenticatable $user, array $credentials, bool $force = false);
Authenticatable
契約
影響可能性:低
Illuminate\Contracts\Auth\Authenticatable
契約已收到一個新的 getAuthPasswordName
方法。此方法負責返回您的可認證實體 (authenticatable entity) 的密碼欄位名稱。
如果您的應用程式或套件定義了一個實作此介面的類別,您應該將新的 getAuthPasswordName
方法添加到您的實作中:
public function getAuthPasswordName()
{
return 'password';
}
Laravel 附帶的預設 User
模型會自動接收此方法,因為該方法包含在 Illuminate\Auth\Authenticatable
Trait 中。
AuthenticationException
類別
影響可能性:非常低
Illuminate\Auth\AuthenticationException
類別的 redirectTo
方法現在需要一個 Illuminate\Http\Request
實例作為其第一個參數。如果您手動捕捉此例外並呼叫 redirectTo
方法,您應該相應地更新您的程式碼:
if ($e instanceof AuthenticationException) {
$path = $e->redirectTo($request);
}
註冊時的 Email 驗證通知
影響可能性:非常低
如果 Registered
事件尚未由您的應用程式的 EventServiceProvider
註冊,SendEmailVerificationNotification
監聽器現在會自動為其註冊。如果您的應用程式的 EventServiceProvider
沒有註冊此監聽器,並且您不希望 Laravel 自動為您註冊,您應該在應用程式的 EventServiceProvider
中定義一個空的 configureEmailVerification
方法:
protected function configureEmailVerification()
{
// ...
}
快取
快取鍵前綴
影響可能性:非常低
之前,如果為 DynamoDB、Memcached 或 Redis 快取儲存定義了快取鍵前綴,Laravel 會在該前綴後附加一個 :
。在 Laravel 11 中,快取鍵前綴不會收到 :
後綴。如果您想保持之前的前綴行為,您可以手動在您的快取鍵前綴中添加 :
後綴。
集合 (Collections)
Enumerable
契約
影響可能性:低
Illuminate\Support\Enumerable
契約的 dump
方法已更新為接受一個變數參數 ...$args
。如果您正在實作此介面,您應該相應地更新您的實作:
public function dump(...$args);
資料庫
SQLite 3.26.0+
影響可能性:高
如果您的應用程式使用 SQLite 資料庫,則需要 SQLite 3.26.0 或更高版本。
Eloquent Model casts
方法
影響可能性:低
基礎 Eloquent 模型類別現在定義了一個 casts
方法,以支援屬性型別轉換的定義。如果您的應用程式的其中一個模型定義了 casts
關聯,它可能會與基礎 Eloquent 模型類別中現在存在的 casts
方法衝突。
修改欄位
影響可能性:高
修改欄位時,您現在必須明確包含變更後希望保留在欄位定義上的所有修飾符。任何遺失的屬性都將被捨棄。例如,為了保留 unsigned
、default
和 comment
屬性,即使這些屬性已經由先前的 migration 分配給欄位,您也必須在變更欄位時明確呼叫每個修飾符。
例如,假設您有一個 migration 創建了一個 votes
欄位,並帶有 unsigned
、default
和 comment
屬性:
Schema::create('users', function (Blueprint $table) {
$table->integer('votes')->unsigned()->default(1)->comment('The vote count');
});
之後,您編寫了一個 migration,也將該欄位變更為 nullable
:
Schema::table('users', function (Blueprint $table) {
$table->integer('votes')->nullable()->change();
});
在 Laravel 10 中,這個 migration 會保留欄位的 unsigned
、default
和 comment
屬性。然而,在 Laravel 11 中,migration 現在還必須包含所有先前在欄位上定義的屬性。否則,它們將被捨棄:
Schema::table('users', function (Blueprint $table) {
$table->integer('votes')
->unsigned()
->default(1)
->comment('The vote count')
->nullable()
->change();
});
change
方法不會變更欄位的索引。因此,您可以在修改欄位時使用索引修飾符來明確添加或捨棄索引:
// Add an index...
$table->bigIncrements('id')->primary()->change();
// Drop an index...
$table->char('postal_code', 10)->unique(false)->change();
如果您不想更新應用程式中所有現有的「變更」migrations 來保留欄位的現有屬性,您可以直接 壓縮您的 migrations:
php artisan schema:dump
一旦您的 migrations 被壓縮,Laravel 將在執行任何待處理的 migrations 之前,使用您應用程式的 schema 檔案來「遷移」資料庫。
浮點數型別
影響可能性:高
double
和 float
migration 欄位型別已重新編寫,以便在所有資料庫中保持一致。
double
欄位型別現在會建立一個與 DOUBLE
等效的欄位,不包含總位數和小數位數(小數點後的位數),這是標準的 SQL 語法。因此,您可以移除 $total
和 $places
的參數:
$table->double('amount');
float
欄位型別現在會建立一個與 FLOAT
等效的欄位,不包含總位數和小數位數(小數點後的位數),但帶有可選的 $precision
規範,以決定儲存大小為 4-byte 單精度欄位或 8-byte 雙精度欄位。因此,您可以移除 $total
和 $places
的參數,並根據您的資料庫文件將可選的 $precision
指定為您所需的值:
$table->float('amount', precision: 53);
unsignedDecimal
、unsignedDouble
和 unsignedFloat
方法已被移除,因為這些欄位型別的 unsigned 修飾符已被 MySQL 棄用,並且從未在其他資料庫系統中標準化。然而,如果您希望繼續使用這些欄位型別的已棄用 unsigned 屬性,您可以將 unsigned
方法鏈接到欄位的定義中:
$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
,以避免破壞性變更或意外行為:
Schema::table('users', function (Blueprint $table) {
$table->char('uuid', 36);
// ...
});
空間型別
影響可能性:低
資料庫 migrations 中的空間欄位型別已重新編寫,以便在所有資料庫中保持一致。因此,您可以從您的 migrations 中移除 point
、lineString
、polygon
、geometryCollection
、multiPoint
、multiLineString
、multiPolygon
和 multiPolygonZ
方法,改為使用 geometry
或 geography
方法:
$table->geometry('shapes');
$table->geography('coordinates');
若要明確限制 MySQL、MariaDB 和 PostgreSQL 上欄位中儲存值的型別或空間參考系統識別符,您可以將 subtype
和 srid
傳遞給該方法:
$table->geometry('dimension', subtype: 'polygon', srid: 0);
$table->geography('latitude', subtype: 'point', srid: 4326);
PostgreSQL 語法中的 isGeometry
和 projection
欄位修飾符已相應移除。
移除 Doctrine DBAL
影響可能性:低
以下列出的 Doctrine DBAL 相關類別和方法已被移除。Laravel 不再依賴此套件,並且不再需要註冊自訂的 Doctrines 型別,即可正確建立和修改先前需要自訂型別的各種欄位型別:
Illuminate\Database\Schema\Builder::$alwaysUsesNativeSchemaOperationsIfPossible
class propertyIlluminate\Database\Schema\Builder::useNativeSchemaOperationsIfPossible()
methodIlluminate\Database\Connection::usingNativeSchemaOperations()
methodIlluminate\Database\Connection::isDoctrineAvailable()
methodIlluminate\Database\Connection::getDoctrineConnection()
methodIlluminate\Database\Connection::getDoctrineSchemaManager()
methodIlluminate\Database\Connection::getDoctrineColumn()
methodIlluminate\Database\Connection::registerDoctrineType()
methodIlluminate\Database\DatabaseManager::registerDoctrineType()
methodIlluminate\Database\PDO
directoryIlluminate\Database\DBAL\TimestampType
classIlluminate\Database\Schema\Grammars\ChangeColumn
classIlluminate\Database\Schema\Grammars\RenameColumn
classIlluminate\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()
來宣告資料庫:
Schema::connection('database')->hasTable('schema.table');
Schema Builder getColumnType()
方法
影響可能性:非常低
Schema::getColumnType()
方法現在總是回傳給定欄位的實際型別,而不是 Doctrine DBAL 等效型別。
資料庫連線介面
影響可能性:非常低
Illuminate\Database\ConnectionInterface
介面已新增一個 scalar
方法。如果您正在定義自己的此介面實作,您應該將 scalar
方法新增到您的實作中:
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
方法新增到您的實作中:
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
配置檔中。
use Illuminate\Support\ServiceProvider;
ServiceProvider::addProviderToBootstrapFile(Provider::class);
佇列
BatchRepository
介面
影響可能性: 極低
Illuminate\Bus\BatchRepository
介面已新增了一個 rollBack
方法。如果您在自己的套件或應用程式中實作此介面,您應該將此方法新增到您的實作中:
public function rollBack();
資料庫交易中的同步化 Job
影響可能性: 極低
以前,同步化 Job (使用 sync
佇列驅動程式的 Job) 會立即執行,無論佇列連線的 after_commit
配置選項是否設定為 true
,或 afterCommit
方法是否在 Job 上被呼叫。
在 Laravel 11 中,同步化佇列 Job 現在將遵循佇列連線或 Job 的「after commit」配置。
速率限制
每秒速率限制
影響可能性: 中
Laravel 11 支援每秒速率限制,而不再限於每分鐘的粒度。關於這項變更,您應該注意各種潛在的破壞性變更。
GlobalLimit
類別的建構函式現在接受秒數而不是分鐘數。此類別並未被文件說明,通常不會被您的應用程式使用:
new GlobalLimit($attempts, 2 * 60);
Limit
類別的建構函式現在接受秒數而不是分鐘數。此類別的所有文件說明的使用方式都限於靜態建構函式,例如 Limit::perMinute
和 Limit::perSecond
。但是,如果您手動實例化此類別,則應更新您的應用程式,向類別的建構函式提供秒數:
new Limit($key, $attempts, 2 * 60);
Limit
類別的 decayMinutes
屬性已更名為 decaySeconds
,現在包含秒數而不是分鐘數。
Illuminate\Queue\Middleware\ThrottlesExceptions
和 Illuminate\Queue\Middleware\ThrottlesExceptionsWithRedis
類別的建構函式現在接受秒數而不是分鐘數:
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 的遷移發佈到您的應用程式:
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 的遷移發佈到您的應用程式:
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 的遷移發佈到您的應用程式:
php artisan vendor:publish --tag=passport-migrations
此外,密碼授權類型預設為禁用。您可以透過在應用程式的 AppServiceProvider
的 boot
方法中呼叫 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 的遷移發佈到您的應用程式:
php artisan vendor:publish --tag=sanctum-migrations
然後,在您的應用程式的 config/sanctum.php
配置檔中,您應該將對 authenticate_session
、encrypt_cookies
和 validate_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 發佈到您的應用程式:
php artisan vendor:publish --tag=telescope-migrations
Spatie Once 套件
影響可能性:中
Laravel 11 現在提供了自己的 once
函式,以確保給定的閉包只會執行一次。因此,如果您的應用程式依賴於 spatie/once
套件,您應該從應用程式的 composer.json
檔案中移除它,以避免衝突。
雜項
我們也鼓勵您查看 laravel/laravel
GitHub 儲存庫中的變更。儘管其中許多變更不是必需的,但您可能會希望讓這些檔案與您的應用程式保持同步。本升級指南將涵蓋其中一些變更,但其他變更,例如設定檔或註解的變更,則不會涵蓋。您可以輕鬆地使用 GitHub 比較工具 來查看這些變更,並選擇對您而言重要的更新。