升级指南
重要更新概览
影响较大
影响中等
- 认证
RegisterController
- 不再支持 Carbon 1.x
- 数据库
Capsule::table
方法 - Eloquent 数组化 & toArray
- Eloquent
BelongsTo::update
方法 - Eloquent 主键类型
- 本地化
Lang::trans
和Lang::transChoice
方法 - 本地化
Lang::getFromJson
方法 - 队列重试限制
- 重发邮箱验证路由
- Input 门面
预计升级时间:1个小时
注:本文档适用于是从 Laravel 5.8 升级到 6.0,我们将尽可能在文档中列出所有重大更新。
PHP 7.2
影响级别:中等
由于 PHP 7.1 从 2019 年 12 月开始不再主动维护,所以 Laravel 6.0 要求 PHP 版本大于等于 7.2。
更新依赖
在 composer.json
文件中更新 laravel/framework
依赖到 ^6.0
。
当然,不要忘了检查应用所使用的第三方扩展包是否支持 Laravel 6.0,如果需要升级的话也要更新。
授权
授权资源 & viewAny
影响级别:高
使用 authorizeResource
方法添加到控制器的授权策略类现在要定义 viewAny
方法,该方法会在用户访问控制器的 index
方法时被调用。否则,调用控制器的 index
方法会被认为是未授权而拒绝。
RegisterController
控制器
影响级别:中等
如果你重写过 Laravel 框架内置 RegisterController
的 register
方法或者 registered
方法,需要确保在对应方法中调用了 parent::register
和 parent::registered
方法,因为 Illuminate\Auth\Events\Registered
事件触发和新用户登录逻辑现在被移到 registered
方法中了,如果你重写了这些方法而没有调用对应的父级方法,用户注册处理会失败。
授权响应
影响级别:低
Illuminate\Auth\Access\Response
类的控制器签名做了调整,你需要更新相应的代码。如果你没有手动构造过授权响应实例,只是在策略类中使用了 allow
和 deny
方法, 则可以忽略此更新:
/**
* Create a new response.
*
* @param bool $allowed
* @param string $message
* @param mixed $code
* @return void
*/
public function __construct($allowed, $message = '', $code = null)
Illuminate\Contracts\Auth\Access\Gate
契约
影响级别:低
Illuminate\Contracts\Auth\Access\Gate
契约新增了一个新的 inspect
方法声明,如果你自行实现过该接口,需要添加这个方法的实现。
Carbon
不再支持 Carbon 1.x
影响级别:中等
由于已经接近维护的生命周期尾期,Carbon 1.x 不再被支持,请升级应用到 Carbon 2.0。
配置
AWS_REGION
环境变量
影响级别:可选
如果你计划使用 Laravel Vapor,那么需要在 config
目录下更新所有已存在的 AWS_REGION
配置为 AWS_DEFAULT_REGION
,此外,你还需要在 .env
文件中更新这个环境变量的名称。
数据库
Capsule table
方法
影响级别:中等
注:此更新只会影响使用了
illuminate/database
依赖包的非 Laravel 应用。
Illuminate\Database\Capsule\Manager
类的 table
方法签名被更新为接收数据表别名作为第二个参数,如果你在 Laravel 应用之外使用了 illuminate/database
,需要更新相应的方法调用:
/**
* Get a fluent query builder instance.
*
* @param \Closure|\Illuminate\Database\Query\Builder|string $table
* @param string|null $as
* @param string|null $connection
* @return \Illuminate\Database\Query\Builder
*/
public static function table($table, $as = null, $connection = null)
cursor
方法
影响级别:低
cursor
方法现在返回的是 Illuminate\Support\LazyCollection
实例而不是 Generator
,LazyCollection
可以像生成器一样迭代:
$users = App\User::cursor();
foreach ($users as $user) {
//
}
Eloquent
BelongsTo::update
方法
影响级别:中等
为了整体一致性,BelongsTo
关联关系类的 update
方法现在用作临时更新查询,意味着它不再提供批量赋值保护或者触发 Eloquent 事件,这使得所有关联关系类型的 update
方法行为一致。
如果你想要通过 BelongsTo
方法更新模型的所属对象,并获取批量赋值更新保护和事件触发,需要在模型自身上调用 update
方法:
// Ad-hoc query... no mass assignment protection or events...
$post->user()->update(['foo' => 'bar']);
// Model update... provides mass assignment protection and events...
$post->user->update(['foo' => 'bar']);
数组化 & toArray
影响级别:中等
Eloquent 模型的 toArray
方法现在会将任何实现了 Illuminate\Contracts\Support\Arrayable
接口的属性转化为数组。
主键类型声明
影响级别:中等
Laravel 6.0 对整型键类型进行了性能优化,如果你使用了字符串作为模型的主键,需要使用模型类的 $keyType
属性声明主键类型:
/**
* The "type" of the primary key ID.
*
* @var string
*/
protected $keyType = 'string';
邮箱验证
重新发送验证路由 HTTP 方法
影响级别:中等
为了免除潜在的 CSRF 攻击,使用 Laravel 内置邮箱验证功能通过路由器注册的 email/resend
路由请求方法已经由 GET
更新为 POST
。因此,你需要更新前端发送请求到该路由的请求类型。例如,如果你是用的是内置的邮箱验证模板代码,需要像这样调整请求方法:
{{ __('Before proceeding, please check your email for a verification link.') }}
{{ __('If you did not receive the email') }},
<form class="d-inline" method="POST" action="{{ route('verification.resend') }}">
@csrf
<button type="submit" class="btn btn-link p-0 m-0 align-baseline">
{{ __('click here to request another') }}
</button>.
</form>
MustVerifyEmail
契约
影响级别:低
Illuminate\Contracts\Auth\MustVerifyEmail
契约中新增了 getEmailForVerification
方法声明,如果你自行实现过该契约,需要添加该方法的实现。这个方法应该返回与对象关联的邮箱地址,如果你的 App\User
模型使用的是 Illuminate\Auth\MustVerifyEmail
Trait,可以忽略此更新,因为该 Trait 内部已经帮我们实现好了。
辅助函数
字符串 & 数组辅助函数包
影响级别:高
所有的 str_
和 array_
辅助函数都被迁移到新的 laravel/helpers Composer 扩展包,如果你使用了这些辅助函数,需要更新所有调用为使用 Illuminate\Support\Str
和 Illuminate\Support\Arr
类提供的相应方法。此外,你还可以安装 laravel/helpers
扩展包来继续使用原函数进行调用:
composer require laravel/helpers
本地化
Lang::trans
& Lang::transChoice
方法
影响级别:中等
翻译器的 Lang::trans
和 Lang::transChoice
方法被重命名为 Lang::get
和Lang::choice
方法。
此外,如果你自行实现了 Illuminate\Contracts\Translation\Translator
契约,需要更新实现类的 trans
和 transChoice
方法名为 get
和 choice
。
Lang::getFromJson
方法
影响级别:中等
Lang::get
和 Lang::getFromJson
方法被合并到一起,之前调用 Lang::getFromJson
方法的地方需要调整为调用 Lang::get
。
邮件
Mandrill & SparkPost 驱动被移除
影响级别:低
mandrill
和 sparkpost
邮件驱动已经被移除,如果你想要继续使用这两个驱动,建议通过社区维护的相应扩展包来实现。
通知
Nexmo 路由被移除
影响级别:低
Nexmo 通知通道中这个不可分割的部分已经从框架核心中移除,如果你依赖 Nexmo 通知路由,需要在通知实体中手动实现 routeNotificationForNexmo
方法。
密码重置
密码验证
影响级别:低
PasswordBroker
不再约束或验证密码。因为密码验证逻辑已经由 ResetPasswordController
控制器处理,导致 broker 的验证逻辑变得冗余,并且不能被自定义,如果你在内置的 ResetPasswordController
之外使用了 PasswordBroker
或者 Password
门面,需要在传递它们到 broker 之前先验证它们。
队列
队列重试限制
影响级别:中等
在之前版本的 Laravel 中,php artisan queue:work
命令会无限期重试队列任务,从 Laravel 6.0 开始,该命令默认只会重试队列任务一次,如果你想要强制任务无限期重试,可以通过 tries=0
选项进行指定:
php artisan queue:work --tries=0
此外,请确保你的应用数据库包含了 failed_jobs
数据表,你可以通过运行 Artisan 命令 queue:failed-table
来生成这个迁移:
php artisan queue:failed-table
请求
Input
门面
影响级别:中等
Input
门面是 Request
门面的翻版,已经被移除,如果你在使用 Input::get
方法,需要将其调整为 Request::input
方法。所有其他调用 Input
门面的地方都需要做类似调整。
任务调度
between
方法
影响级别:低
在之前版本的 Laravel 中,调度器的 between
方法会出现跨越日期边界的混乱行为,例如:
$schedule->command('list')->between('23:00', '4:00');
对大多数用户来说,编写上述调度期望的行为是在 23:00 到 4:00 之间每分钟运行一次 list
命令,然而,在之前版本的 Laravel 中,这个调度器的执行逻辑反过来了,会在 4:00 到 23:00 之间每分钟执行一次 list
命令,在 Laravel 6.0 中,这一错误行为被纠正。
存储
Rackspace 存储驱动被移除
影响级别:低
存储驱动 rackspace
被移除,如果你想要继续使用 Rackspace 作为存储驱动,建议使用社区维护的扩展包来替代。
URL 生成
路由 URL 生成 & 提取参数
在之前版本的 Laravel 中,传递关联数组参数到 route
辅助函数或者 URL::route
方法生成指定路由(包含可选参数)对应 URL 时偶尔会出现将这些参数作为 URI 值的现象,即使传递参数值在路由路径中没有匹配键。从 Laravel 6.0 开始,这些值会被追加到查询字符串中,如下所示:
Route::get('/profile/{location?}', function ($location = null) {
//
})->name('profile');
// Laravel 5.8: http://example.com/profile/active
echo route('profile', ['status' => 'active']);
// Laravel 6.0: http://example.com/profile?status=active
echo route('profile', ['status' => 'active']);
其它
我们还鼓励你查看 laravel/laravel
代码仓库的更新日志。尽管其中的很多更新不是必须的,但是你可以将应用中的这些文件与代码仓库保持同步。其中的一些更新已经在这篇升级指南中覆盖到了,但是还有很多其他的小更新比如配置文件或注释的微调,就不会一一指出。你可以通过 GitHub 比较工具 轻松查看变更以便选择那些对你而言更为重要的更新。
2 Comments
我靠,版本迭代这么快!
半年一次 这是 Laravel 主版本发布的节奏