升级指南

重要更新概览

影响较大

影响中等

预计升级时间: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 框架内置 RegisterControllerregister 方法或者 registered 方法,需要确保在对应方法中调用了 parent::registerparent::registered 方法,因为 Illuminate\Auth\Events\Registered 事件触发和新用户登录逻辑现在被移到 registered 方法中了,如果你重写了这些方法而没有调用对应的父级方法,用户注册处理会失败。

授权响应

影响级别:低

Illuminate\Auth\Access\Response 类的控制器签名做了调整,你需要更新相应的代码。如果你没有手动构造过授权响应实例,只是在策略类中使用了 allowdeny 方法, 则可以忽略此更新:

/**
 * 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 实例而不是 GeneratorLazyCollection 可以像生成器一样迭代:

$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\StrIlluminate\Support\Arr 类提供的相应方法。此外,你还可以安装 laravel/helpers 扩展包来继续使用原函数进行调用:

composer require laravel/helpers

本地化

Lang::trans & Lang::transChoice 方法

影响级别:中等

翻译器的 Lang::transLang::transChoice 方法被重命名为 Lang::getLang::choice 方法。

此外,如果你自行实现了 Illuminate\Contracts\Translation\Translator 契约,需要更新实现类的 transtransChoice 方法名为 getchoice

Lang::getFromJson 方法

影响级别:中等

Lang::getLang::getFromJson 方法被合并到一起,之前调用 Lang::getFromJson 方法的地方需要调整为调用 Lang::get

邮件

Mandrill & SparkPost 驱动被移除

影响级别:低

mandrillsparkpost 邮件驱动已经被移除,如果你想要继续使用这两个驱动,建议通过社区维护的相应扩展包来实现。

通知

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 比较工具 轻松查看变更以便选择那些对你而言更为重要的更新。

上一篇: 新版特性

下一篇: 贡献指南