升级指南

从 5.6 升级到 5.7

预计升级时间:10~15 分钟

我们会记录每个可能的破坏性更改。由于其中一些更改在框架内部,因此实际可能只有一部分会影响您的应用。

更新依赖

composer.json 文件中将 laravel/framework 的依赖更新至 5.7.*

如果使用了 Laravel Passport,还应该将 laravel/passport 的依赖更新至 ^7.0

当然,最后别忘了检查应用使用的第三方扩展包,是否适用于 Laravel 5.7。

应用

register 方法

影响的可能性:非常低

Illuminate\Foundation\Application 类的 register 方法中,未使用的参数 options 已被移除,如果您重写了此方法,则需要更新该方法的参数:

/**
 * 在应用中注册服务提供者
 *
 * @param  \Illuminate\Support\ServiceProvider|string  $provider
 * @param  bool   $force
 * @return \Illuminate\Support\ServiceProvider
 */
public function register($provider, $force = false);

Artisan

任务调度连接 & 队列

影响的可能性:低

在任务类中,如果没有明确地传递一个连接/任务给 job 方法,那么 $schedule->job 方法会考虑使用任务类的 queueconnection 属性。

通常来说,这应该视为一个 bug 修复;但还是列为一个破坏性更改。如果您遇到任何关于此更改的问题,请告诉我们

静态资源

assets 目录铺平

影响的可能性:无

在新的 Laravel 5.7 应用中,含有 JavaScript 脚本和 CSS 样式文件的 assetsresources 目录下被铺平。它 不会 影响现有的应用,也不需要为此进行任何更改。

不过,如果您想应用此更改,可以将 resources/assets/* 目录的所有文件上移一级:

  • resources/assets/js/* 移动到 resources/js/*
  • resources/assets/sass/* 移动到 resources/sass/*

然后,在 webpack.mix.js 中更新所有路径的引用:

mix.js('resources/js/app.js', 'public/js')
   .sass('resources/sass/app.scss', 'public/css');

认证

Authenticate 中间件

影响的可能性:低

Illuminate\Auth\Middleware\Authenticate 中间件中,authenticate 方法已更新为接收传入的请求 $request 作为其第一个参数,如果您在自己的 Authenticate 中间件中重写了此方法,则需要更新中间件该方法的参数:

/**
 * 确认用户是否已登录到任何给定的看守器
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  array  $guards
 * @return void
 *
 * @throws \Illuminate\Auth\AuthenticationException
 */
protected function authenticate($request, array $guards)

ResetsPasswords Trait

影响的可能性:低

ResetsPasswords Trait 中,受保护的 sendResetResponse 方法现在接收传入的 Illuminate\Http\Request 作为其第一个参数。如果您重写了此方法,则需要更新该方法的参数:

/**
 * 获取成功重置密码的响应
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  string  $response
 * @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
 */
protected function sendResetResponse(Request $request, $response)

SendsPasswordResetEmails Trait

影响的可能性:低

SendsPasswordResetEmails Trait 中,受保护的方法 sendResetLinkResponse 现在接收传入的 Illuminate\Http\Request 作为第一个参数。如果您重写了此方法,需要修改该方法的参数:

/**
 * 获取取得重置密码链接的响应
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  string  $response
 * @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
 */
protected function sendResetLinkResponse(Request $request, $response)

授权

Gate Contract

影响的可能性:非常低

raw 方法的可见性由 protected 更改为 public。此外,它被添加到 Illuminate/Contracts/Auth/Access/Gate Contract

/**
 * 获取授权回调的结果
 *
 * @param  string  $ability
 * @param  array|mixed  $arguments
 * @return mixed
 */
public function raw($ability, $arguments = []);

如果您实现了此接口,那么应该添加该方法到实现中。

Blade

or 操作符

影响的可能性:高

Blade 的「or」操作符被移除了,它和 PHP 内置的「空合并操作符」?? 有相同的功能:

// Laravel 5.6
{{ $foo or 'default' }}

// Laravel 5.7
{{ $foo ?? 'default' }}

缓存

影响的可能性:非常高

新添加了一个 data 目录到 storage/framework/cache 路径下。您应该在应用中创建此目录:

mkdir -p storage/framework/cache/data;

然后,在新建的 data 目录下添加 .gitignore 文件:

cp storage/framework/cache/.gitignore storage/framework/cache/data/.gitignore

最后,更新 storage/framework/cache/.gitignore 文件内容

*
!data/
!.gitignore

Carbon

影响的可能性:非常低

Carbon「macros」不再由 Laravel 的扩展库处理,而是直接通过 Carbon 库进行处理。我们希望这没有对您的代码造成影响;如果遇到问题,请 联系我们

集合

split 方法

影响可能性:低

split 方法更新为 始终返回请求数目的「组」,除非原集合的元素总数小于请求的集合的元素个数。通常来说,这是一个 bug 修复;但是,仍将其归为一个破坏性更新。

Cookie

Factory Contract 方法的参数

影响可能性:非常低

Illuminate/Contracts/Cookie/Factory 接口的 makeforever 方法的参数 已更改。如果您实现了此接口,则应该更新该方法。

数据库

softDeletesTz 迁移方法

影响可能性:低

数据库结构生成器的 softDeletesTz 方法现在接收表名作为其第一个参数,而 $precision 字段已经移动到了第二个参数的位置:

/**
 * 在表中添加一个「deleted at」的时间戳
 *
 * @param  string  $column
 * @param  int  $precision
 * @return \Illuminate\Support\Fluent
 */
public function softDeletesTz($column = 'deleted_at', $precision = 0)

ConnectionInterface Contract

影响可能性:非常低

Illuminate\Contracts\Database\ConnectionInterface Contract 的 selectselectOne 方法添加了新的 $useReadPdo 参数:

/**
 * 执行一条 select 语句并返回单个结果
 *
 * @param  string  $query
 * @param  array   $bindings
 * @param  bool  $useReadPdo
 * @return mixed
 */
public function selectOne($query, $bindings = [], $useReadPdo = true);

/**
 * 对数据库执行 select 语句
 *
 * @param  string  $query
 * @param  array   $bindings
 * @param  bool  $useReadPdo
 * @return array
 */
public function select($query, $bindings = [], $useReadPdo = true);

此外,cursor 方法也添加到了 Contract 中:

/**
 * 在数据库执行 select 语句并返回一个生成器
 *
 * @param  string  $query
 * @param  array  $bindings
 * @param  bool  $useReadPdo
 * @return \Generator
 */
public function cursor($query, $bindings = [], $useReadPdo = true);

如果您实现了此接口,请将该方法添加到实现中。

迁移命令的输出

影响可能性:非常低

核心迁移命令已更新为 在迁移类上设置输出实例。如果您重写或继承了迁移命令,则应使用 $this->migrator->setOutput($this->output) 而不是 $this->migrator->getNotes()

SQL Server 驱动优先级

影响可能性:低

在 Laravel 5.7 之前, PDO_DBLIB 驱动用作 SQL Server PDO 的默认驱动。该驱动被认为是微软废弃的。在 Laravel 5.7 中,如果 PDO_SQLSRV 驱动可用,将被用作默认驱动。或者,您可以选择使用 PDO_ODBC 驱动:

'sqlsrv' => [
    // ...
    'odbc' => true,
    'odbc_datasource_name' => 'your-odbc-dsn',
],

如果这些驱动都不可用, 那么 Laravel 会使用 PDO_DBLIB 驱动。

SQLite 外键

影响可能性:中

SQLite 不支持删除外键。因此,在数据表上使用 dropForeign 方法时会抛出异常。通常来说,这应该视为一个 bug 修复;但还是列为一个破坏性更改。

如果您要在多种数据库上运行迁移,可以考虑在迁移中使用 DB::getDriverName() 跳过 SQLite 不支持的外键方法。

调试

Dumper 类

影响可能性:非常低

由于使用 Symfony 原生的变量调试输出类:Symfony\Component\VarDumper\VarDumperSymfony\Component\VarDumper\Dumper\HtmlDumper,因此 Illuminate\Support\Debug\DumperIlluminate\Support\Debug\HtmlDumper 类已被移除。

Eloquent

latestoldest 方法

影响可能性:低

Eloquent 查询构造器的 latestoldest 方法已更新,可以在 Eloquent 模型中指定「created at」对应的数据库字段。通常来说,这应该视为一个 bug 修复;但还是列为一个破坏性更改。

wasChanged 方法

影响可能性:非常低

Eloquent 的 wasChanged 方法会在 updated 模型事件 之前 调用。通常来说,这应该视为一个 bug 修复;但还是列为一个破坏性更改。如果您遇到任何关于此更改的问题,请告诉我们

PostgreSQL 特殊浮点值

影响的可能性:低

PostgreSQL 支持 Infinity-InfinityNaN 浮点值。在 Laravel 5.7 之前,当 Eloquent 中的数据转换类型是 floatdoublereal 时,它们会被转换成 0

而在 Laravel 5.7 中,这些值会被转换成对应的 PHP 常量 INF-INFNAN

邮箱验证

影响的可能性:可选

如果您使用 Laravel 新的 邮箱验证 服务,则需要在应用中添加额外的脚手架。首先,在应用中添加 VerificationControllerApp\Http\Controllers\Auth\VerificationController

接着将 App\User 模型修改为实现 MustVerifyEmail Contract:

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable implements MustVerifyEmail
{
    use Notifiable;

    // ...
}

为了可以使用 verified 中间件验证用户是否有权访问给定路由,还需要在 app/Http/Kernel.php 文件的 $routeMiddleware 属性中包含新的中间件:

protected $routeMiddleware = [
    'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
    'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
    'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
    'can' => \Illuminate\Auth\Middleware\Authorize::class,
    'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
    'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
    'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
];

然后添加对应的验证视图。该视图应该位于 resources/views/auth/verify.blade.php。视图内容可以在 GitHub 上获取。

接下来,在用户表中添加 email_verified_at 字段用于存储邮箱验证的时间:

$table->timestamp('email_verified_at')->nullable();

为了在用户注册时发送验证邮件,在 App\Providers\EventServiceProvider 类中注册如下事件和监听器:

use Illuminate\Auth\Events\Registered;
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;

/**
 * 应用的事件监听器映射
 *
 * @var array
 */
protected $listen = [
    Registered::class => [
        SendEmailVerificationNotification::class,
    ],
];

最后,在调用 Auth::routes 方法时,传递 verify 选项到该方法:

Auth::routes(['verify' => true]);

文件系统

Filesystem Contract 方法

影响的可能性:低

Illuminate\Contracts\Filesystem\Filesystem Contract 中添加了 readStreamwriteStream 方法。如果您实现了此接口,则应该添加这些方法到实现中。

哈希

Hash:check 方法

影响的可能性:无

check 方法现在 可选 检查哈希算法是否和配置的算法匹配。

邮件

邮件动态传参转换

影响的可能性:中

向邮件视图中动态传递的变量现在会 自动转换为「驼峰命名」,使动态邮件变量和动态视图变量表现一致。由于动态邮件变量不在 Laravel 文档中,因此影响应用的可能性很小。

模板主题

影响的可能性:中

如果您定制了 Markdown 邮件模板默认的主题样式,那么需要重新发布并再次定制。按钮的颜色类由 bluegreenred 改名为 primarysuccess 以及 error

队列

QUEUE_DRIVER 环境变量

影响的可能性:非常低

QUEUE_DRIVER 环境变量已改名为 QUEUE_CONNECTION。除非您修改了 config/queue.php 配置文件,否则升级到 Laravel 5.7 不会对应用有任何影响。

路由

Route::redirect 方法

影响的可能性:高

Route::redirect 方法现在返回 302 HTTP 状态码的重定向。添加了 permanentRedirect 方法来允许 301 重定向。

// 返回 302 重定向
Route::redirect('/foo', '/bar');

// 返回 301 重定向
Route::redirect('/foo', '/bar', 301);

// 返回 301 重定向
Route::permanentRedirect('/foo', '/bar');

addRoute 方法

影响的可能性:低

Illuminate\Routing\Router 类的 addRoute 方法可见性由 protected 更改为 public

验证

嵌套验证数据

影响的可能性:中

在之前版本的 Laravel 中,validate 方法对嵌套验证规则未返回正确的数据。在 Laravel 5.7 中已修复:

$data = Validator::make([
    'person' => [
        'name' => 'Taylor',
        'job' => 'Developer'
    ]
], ['person.name' => 'required'])->validate();

dump($data);

// 以前的行为
['person' => ['name' => 'Taylor', 'job' => 'Developer']]

// 新的行为
['person' => ['name' => 'Taylor']]

Validator Contract

影响的可能性:非常低

Illuminate/Contracts/Validation/Validator Contract 新增 validate 方法:

/**
 * 对数据进行验证规则验证
 *
 * @return array
 */
public function validate();

如果您实现了此接口,那么应该添加此方法到实现中。

其它

我们推荐您查阅 laravel/laravel GitHub 仓库 中的更改。虽然很多修改不是必需的,但您可能希望使这些文件和应用保持同步。该升级指南只涉及了部分更改,其它如配置文件或注释等更改则没有提到。您可以通过 GitHub 比较工具 轻松查看这些更改并选择对您重要的更新。