升级指南
高影响变更
中等影响变更
从 7.x 升级到 8.0
预计升级时间:15 分钟
我们尝试记录每一个可能的重大变更。由于这些变更中的一些位于框架的偏僻部分,只有一部分变更可能实际影响到您的应用程序。
需要 PHP 7.3.0
影响可能性:中等
新的最低 PHP 版本现在是 7.3.0。
更新依赖
在您的 composer.json
文件中更新以下依赖:
guzzlehttp/guzzle
到^7.0.1
facade/ignition
到^2.3.6
laravel/framework
到^8.0
laravel/ui
到^3.0
nunomaduro/collision
到^5.0
phpunit/phpunit
到^9.0
以下第一方包有新的主要版本以支持 Laravel 8。如果适用,您应该在升级前阅读它们各自的升级指南:
此外,Laravel 安装器已更新以支持 composer create-project
和 Laravel Jetstream。任何低于 4.0 的安装器将在 2020 年 10 月后停止工作。您应尽快将全局安装器升级到 ^4.0
。
最后,检查您的应用程序使用的任何其他第三方包,并验证您使用的是支持 Laravel 8 的正确版本。
集合
isset
方法
影响可能性:低
为了与典型的 PHP 行为保持一致,Illuminate\Support\Collection
的 offsetExists
方法已更新为使用 isset
而不是 array_key_exists
。这可能会在处理值为 null
的集合项时导致行为变化:
$collection = collect([null]);
// Laravel 7.x - true
isset($collection[0]);
// Laravel 8.x - false
isset($collection[0]);
数据库
Seeder 和 Factory 命名空间
影响可能性:高
Seeders 和 factories 现在有命名空间。为了适应这些变化,请将 Database\Seeders
命名空间添加到您的 seeder 类中。此外,之前的 database/seeds
目录应重命名为 database/seeders
:
<?php
namespace Database\Seeders;
use App\Models\User;
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* 为应用程序的数据库填充数据。
*
* @return void
*/
public function run()
{
...
}
}
如果您选择使用 laravel/legacy-factories
包,则不需要对您的 factory 类进行更改。但是,如果您正在升级您的 factories,您应该将 Database\Factories
命名空间添加到这些类中。
接下来,在您的 composer.json
文件中,从 autoload
部分中删除 classmap
块,并添加新的命名空间类目录映射:
"autoload": {
"psr-4": {
"App\\": "app/",
"Database\\Factories\\": "database/factories/",
"Database\\Seeders\\": "database/seeders/"
}
},
Eloquent
模型工厂
影响可能性:高
Laravel 的 模型工厂 功能已被完全重写以支持类,并且与 Laravel 7.x 风格的工厂不兼容。然而,为了简化升级过程,创建了一个新的 laravel/legacy-factories
包,以便在 Laravel 8.x 中继续使用现有的工厂。您可以通过 Composer 安装此包:
composer require laravel/legacy-factories
Castable
接口
影响可能性:低
Castable
接口的 castUsing
方法已更新为接受一个参数数组。如果您正在实现此接口,您应该相应地更新您的实现:
public static function castUsing(array $arguments);
增量/减量事件
影响可能性:低
在 Eloquent 模型实例上执行 increment
或 decrement
方法时,现在将触发适当的“更新”和“保存”相关的模型事件。
事件
EventServiceProvider
类
影响可能性:低
如果您的 App\Providers\EventServiceProvider
类包含一个 register
函数,您应该确保在此方法的开头调用 parent::register
。否则,您的应用程序的事件将不会被注册。
Dispatcher
合约
影响可能性:低
Illuminate\Contracts\Events\Dispatcher
合约的 listen
方法已更新,使 $listener
属性可选。此更改是为了支持通过反射自动检测处理的事件类型。如果您正在手动实现此接口,您应该相应地更新您的实现:
public function listen($events, $listener = null);
框架
维护模式更新
影响可能性:可选
Laravel 8.x 的 维护模式 功能已得到改进。现在支持预渲染维护模式模板,消除了最终用户在维护模式期间遇到错误的可能性。然而,为了支持这一点,必须将以下行添加到您的 public/index.php
文件中。这些行应直接放在现有的 LARAVEL_START
常量定义下:
define('LARAVEL_START', microtime(true));
if (file_exists($maintenance = __DIR__.'/../storage/framework/maintenance.php')) {
require $maintenance;
}
php artisan down --message
选项
影响可能性:中等
php artisan down
命令的 --message
选项已被移除。作为替代方案,请考虑使用您选择的消息 预渲染您的维护模式视图。
php artisan serve --no-reload
选项
影响可能性:低
php artisan serve
命令中添加了一个 --no-reload
选项。这将指示内置服务器在检测到环境文件更改时不重新加载服务器。此选项主要在 CI 环境中运行 Laravel Dusk 测试时有用。
Manager $app
属性
影响可能性:低
Illuminate\Support\Manager
类中先前已弃用的 $app
属性已被移除。如果您依赖此属性,您应该使用 $container
属性。
elixir
助手
影响可能性:低
先前已弃用的 elixir
助手已被移除。仍在使用此方法的应用程序建议升级到 Laravel Mix。
邮件
sendNow
方法
影响可能性:低
先前已弃用的 sendNow
方法已被移除。请改用 send
方法。
分页
分页默认值
影响可能性:高
分页器现在使用 Tailwind CSS 框架 作为其默认样式。为了继续使用 Bootstrap,您应该在应用程序的 AppServiceProvider
的 boot
方法中添加以下方法调用:
use Illuminate\Pagination\Paginator;
Paginator::useBootstrap();
队列
retryAfter
方法
影响可能性:高
为了与 Laravel 的其他功能保持一致,队列作业、邮件、通知和监听器的 retryAfter
方法和 retryAfter
属性已重命名为 backoff
。您应该在应用程序的相关类中更新此方法/属性的名称。
timeoutAt
属性
影响可能性:高
队列作业、通知和监听器的 timeoutAt
属性已重命名为 retryUntil
。您应该在应用程序的相关类中更新此属性的名称。
allOnQueue()
/ allOnConnection()
方法
影响可能性:高
为了与其他调度方法保持一致,使用作业链的 allOnQueue()
和 allOnConnection()
方法已被移除。您可以使用 onQueue()
和 onConnection()
方法代替。这些方法应在调用 dispatch
方法之前调用:
ProcessPodcast::withChain([
new OptimizePodcast,
new ReleasePodcast
])->onConnection('redis')->onQueue('podcasts')->dispatch();
请注意,此更改仅影响使用 withChain
方法的代码。使用全局 dispatch()
助手时,allOnQueue()
和 allOnConnection()
仍然可用。
失败作业表批处理支持
影响可能性:可选
如果您计划使用 Laravel 8.x 的 作业批处理 功能,您的 failed_jobs
数据库表需要更新。首先,应在您的表中添加一个新的 uuid
列:
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
Schema::table('failed_jobs', function (Blueprint $table) {
$table->string('uuid')->after('id')->nullable()->unique();
});
接下来,您的 queue
配置文件中的 failed.driver
配置选项应更新为 database-uuids
。
此外,您可能希望为现有的失败作业生成 UUID:
DB::table('failed_jobs')->whereNull('uuid')->cursor()->each(function ($job) {
DB::table('failed_jobs')
->where('id', $job->id)
->update(['uuid' => (string) Illuminate\Support\Str::uuid()]);
});
路由
自动控制器命名空间前缀
影响可能性:可选
在 Laravel 的先前版本中,RouteServiceProvider
类包含一个值为 App\Http\Controllers
的 $namespace
属性。此属性的值用于自动为控制器路由声明和控制器路由 URL 生成添加前缀,例如在调用 action
助手时。
在 Laravel 8 中,此属性默认设置为 null
。这允许您的控制器路由声明使用标准的 PHP 可调用语法,这为许多 IDE 提供了更好的跳转到控制器类的支持:
use App\Http\Controllers\UserController;
// 使用 PHP 可调用语法...
Route::get('/users', [UserController::class, 'index']);
// 使用字符串语法...
Route::get('/users', 'App\Http\Controllers\UserController@index');
在大多数情况下,这不会影响正在升级的应用程序,因为您的 RouteServiceProvider
仍将包含具有其先前值的 $namespace
属性。然而,如果您通过创建一个全新的 Laravel 项目来升级您的应用程序,您可能会遇到此破坏性更改。
如果您希望继续使用原始的自动前缀控制器路由,您可以简单地在您的 RouteServiceProvider
中设置 $namespace
属性的值,并更新 boot
方法中的路由注册以使用 $namespace
属性:
class RouteServiceProvider extends ServiceProvider
{
/**
* 应用程序的“home”路由的路径。
*
* 这用于 Laravel 认证在登录后重定向用户。
*
* @var string
*/
public const HOME = '/home';
/**
* 如果指定,此命名空间将自动应用于您的控制器路由。
*
* 此外,它被设置为 URL 生成器的根命名空间。
*
* @var string
*/
protected $namespace = 'App\Http\Controllers';
/**
* 定义您的路由模型绑定、模式过滤器等。
*
* @return void
*/
public function boot()
{
$this->configureRateLimiting();
$this->routes(function () {
Route::middleware('web')
->namespace($this->namespace)
->group(base_path('routes/web.php'));
Route::prefix('api')
->middleware('api')
->namespace($this->namespace)
->group(base_path('routes/api.php'));
});
}
/**
* 为应用程序配置速率限制器。
*
* @return void
*/
protected function configureRateLimiting()
{
RateLimiter::for('api', function (Request $request) {
return Limit::perMinute(60)->by(optional($request->user())->id ?: $request->ip());
});
}
}
调度
cron-expression
库
影响可能性:低
Laravel 对 dragonmantank/cron-expression
的依赖已从 2.x
更新到 3.x
。这不应在您的应用程序中造成任何破坏性更改,除非您直接与 cron-expression
库交互。如果您直接与此库交互,请查看其 变更日志。
会话
Session
合约
影响可能性:低
Illuminate\Contracts\Session\Session
合约已接收一个新的 pull
方法。如果您正在手动实现此合约,您应该相应地更新您的实现:
/**
* 获取给定键的值,然后忘记它。
*
* @param string $key
* @param mixed $default
* @return mixed
*/
public function pull($key, $default = null);
测试
decodeResponseJson
方法
影响可能性:低
属于 Illuminate\Testing\TestResponse
类的 decodeResponseJson
方法不再接受任何参数。请考虑使用 json
方法代替。
assertExactJson
方法
影响可能性:中等
assertExactJson
方法现在要求比较数组的数字键匹配并且顺序相同。如果您希望在不要求数字键数组顺序相同的情况下将 JSON 与数组进行比较,您可以使用 assertSimilarJson
方法。
验证
数据库规则连接
影响可能性:低
unique
和 exists
规则现在将在执行查询时尊重 Eloquent 模型的指定连接名称(通过模型的 getConnectionName
方法访问)。
杂项
我们还鼓励您查看 laravel/laravel
GitHub 仓库 中的更改。虽然这些更改中的许多不是必需的,但您可能希望将这些文件与您的应用程序保持同步。这些更改中的一些将在本升级指南中介绍,但其他更改,例如配置文件或注释的更改,将不会介绍。您可以使用 GitHub 比较工具 轻松查看更改,并选择哪些更新对您来说是重要的。