升级导引

从 5.2 升级到 5.3

预计升级耗时:2~3 小时

{note} 我们尽量罗列出每一个不兼容的变更。但因为其中一些不兼容变更只存在于框架很不起眼的地方,事实上只有一小部分会真正影响到你的应用程序。

更新依赖

composer.json 文件中将你的 laravel/framework 更新为 5.3.*

此外, 你应该更新你的 symfony/css-selectorsymfony/dom-crawler 依赖到 3.1.*composer.json 文件的 require-dev 部分。

PHP & HHVM

Laravel 5.3 需要 PHP 5.6.4 或者更高的版本。由于不包含和 PHP 5.6+ 相同的语言特性,HHVM 不再受到官方支持。

弃用的功能

所有被列在 Laravel 5.2 升级指南 内的废弃项都已经从框架中彻底移除。请回顾该列表以确保你没有继续使用这些废弃的特性。

应用服务提供者

你可以从 EventServiceProviderRouteServiceProviderAuthServiceProvider 类的 boot 方法上移除参数。任何给定参数的调用都可以被转化为等效的 facade。所以,举个栗子,除了在 $dispatcher 参数上调用方法,你可以直接调用 Event facade。同样,除了在 $router 参数上调用方法,你可以直接调用 Route facade,$gate 亦然(可直接调用 Gate facade)。

{note} 当把方法调用转化为 facades 时,请先在服务提供者顶部引入 facade 类。

数组

键/值 顺序变更

现在,Arr 类中的 firstlastwhere 方法将「值」作为第一个参数传递给闭包。例如:

Arr::first($array, function ($value, $key) {
    return ! is_null($value);
});

在 Laravel 之前的版本中,$key 被作为第一个参数。由于大多数情况下只需要用到 $value,所以 现在我们把它作为第一个参数。你应该在应用程序中做一次「全局搜索」,以确保 $value 是第一个被传递到闭包的参数。

Artisan

make:console 命令

make:console 命令已被重命名为 make:command

用户认证

认证脚手架

框架默认提供的两个认证控制器现在被拆分成了 4 个更小的控制器。这使得每一个控制器职责更加明晰。升级认证控制器最简单的方法就是直接从 GitHub 上复制一份新的认证控制器 到你自己的项目。

同时,你需要在 routes/web.php 文件中调用 Auth::routes() 方法。该方法会注册相应的路由到新的认证控制器。

如果你曾对认证控制器进行过编辑修改,那么在升级后别忘了重新设置一遍。例如,你曾修改过用户认证中的 guard,那么你就需要重写新控制器中的 guard 方法。你可以检查每个认证控制器的特性来决定哪些方法需要被重写。

{tip} 如果你没有自定义过用户认证控制器,则无需重新设置。

密码重置邮件

密码重置邮件现在使用了新的 Laravel 消息通知特性。如果你想自定义在发送密码重置链接时被发送的消息,你可以重写 Illuminate\Auth\Passwords\CanResetPassword trait 的 sendPasswordResetNotification 方法。

User 模型 必须 使用新的 Illuminate\Notifications\Notifiable trait,否则密码重置邮件无法成功发送。

<?php

namespace App;

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

class User extends Authenticatable
{
    use Notifiable;
}

{note} 不要忘记注册 Illuminate\Notifications\NotificationServiceProviderconfig/app.php 配置文件中的 providers 数组。

以 POST 方式登出

Auth::routes 方法现在注册 POST 路由到 /logout,取代之前的 GET 路由。这可以阻止其他网页应用将你的用户从你的应用中登出。这里有两个方案能让你正确升级到 5.3,要么将所有登出请求都转为使用 POST 动词,要么注册你自己的 GET 路由到 /logout

Route::get('/logout', 'Auth\LoginController@logout');

用户授权

带类名的策略调用

一些策略方法只接收当前被认证的用户,而不需要被授权的模型实例。这种情况在授权 create 行为时是最常见的。例如,如果你正在创建一个博客,你可能希望检查一个用户是否被授权了新建文章的权限。

当定义不需要接受模型实例的策略方法时,比如 create 方法,类名将不再作为第二个参数被传递到这些方法。你的方法只需要接收被认证的用户实例:

/**
 * Determine if the given user can create posts.
 *
 * @param  \App\User  $user
 * @return bool
 */
public function create(User $user)
{
    //
}

AuthorizesResources Trait

AuthorizesResources trait 现已被合并到 AuthorizesRequests trait。你需要从 app/Http/Controllers/Controller.php 文件中移除 AuthorizesResources trait。

Blade

自定义指令

在 Laravel 之前的版本中,当使用 directive 方法注册自定义 Blade 指令时,被传递到指令回调的 $expression 包含最外层的括号。在 Laravel 5.3 中,这些最外层的括号将不再被包含在表达式中。请移步 Blade 扩展 并确保你的自定义 Blade 指令仍然能正常工作。

广播

服务提供者

Laravel 5.3 对事件广播进行了很多改进。你需要从 Github 上复制一份新的 BroadcastServiceProvider 到你的 app/Providers 目录,并将它注册到 config/app.php 配置文件的 providers 数组里。

缓存

扩展闭包绑定 & $this

当在闭包中调用 Cache::extend 方法时,$this 将会被绑定到 CacheManager 实例,这允许你从扩展闭包里调用 Cahche 的所有方法:

Cache::extend('memcached', function ($app, $config) {
    try {
        return $this->createMemcachedDriver($config);
    } catch (Exception $e) {
        return $this->createNullDriver($config);
    }
});

Cashier

如果正在使用 Cashier 交易工具包,你需要升级你的 laravel/cashier 包到 ~7.0 版本(>=7.0 并且 <8.0)。这一版的 Cashier 只更新了内部方法以兼容 Laravel 5.3,请放心使用。

集合

键/值 顺序变更

集合中的 firstlastcontains 方法现在将「值」作为第一个参数传递给给定闭包。例如:

$collection->first(function ($value, $key) {
    return ! is_null($value);
});

在 Laravel 之前的版本中,$key 被作为第一个参数。由于大多数情况下只需要用到 $value,所以 现在我们把它作为第一个参数。你应该在应用程序中做一次「全局搜索」,以确保 $value 是第一个被传递到闭包的参数。

默认情况下集合的 where 匹配方式为「宽松」模式

集合的 where 方法由默认的严格匹配改为了「宽松」匹配。如果你想要执行严格匹配,可以使用 whereStrict 方法。

同时,where 方法不再接收用于指明「严格」匹配的第三个参数。你应该根据需要显示地调用 wherewhereStrict 方法。

控制器

类构造器中的 Session

在 Laravel 之前的版本中,尽管你能够在控制器的类构造器中访问 session 变量和被认证的用户实例,但我们从未把这设计为框架的特性。在 Laravel 5.3 中,你无法再这样使用了,因为这个时候中间件还没有运行。

作为一种替代方案,你可以在你的控制器类构造方法中定义一个基于中间件的闭包。为了使用这一特性,请先确认你的 Laravel 版本大于等于 5.3.4:

<?php

namespace App\Http\Controllers;

use App\User;
use Illuminate\Support\Facades\Auth;
use App\Http\Controllers\Controller;

class ProjectController extends Controller
{
    /**
     * All of the current user's projects.
     */
    protected $projects;

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware(function ($request, $next) {
            $this->projects = Auth::user()->projects;

            return $next($request);
        });
    }
}

当然,你也可以选择在控制器行为中访问请求的 session 数据或被认证的用户实例,这可以通过类型提示 Illuminate\Http\Request 类来实现:

/**
 * Show all of the projects for the current user.
 *
 * @param  \Illuminate\Http\Request  $request
 * @return Response
 */
public function index(Request $request)
{
    $projects = $request->user()->projects;

    $value = $request->session()->get('key');

    //
}

数据库

集合

现在,查询构造器 将返回 Illuminate\Support\Collection 实例,而不再是简单的数组。这使得通过查询构造器和 Eloquent 方式返回的数据类型保持一致。

如果你想继续返回简单的 PHP 数组来保持向后兼容,可以在查询构造器的 get 方法后面跟上 all 方法。

$users = DB::table('users')->get()->all();

Eloquent 的 $morphClass 属性

Eloquent 中的 $morphClass 属性现已被移除,取而代之的是定义一个「morph map」。定义一个 morph map 能够提供对预加载和解析多态关联额外问题的支持。如果你之前使用了 $morphClass 属性,请用下面的语句迁移到 morphMap

Relation::morphMap([
    'YourCustomMorphName' => YourModel::class,
]);

例如,你之前定义了如下 $morphClass

class User extends Model
{
    protected $morphClass = 'user'
}

现在,你应该在 AppServiceProviderboot 方法中定义如下 morphMap

use Illuminate\Database\Eloquent\Relations\Relation;

Relation::morphMap([
    'user' => User::class,
]);

Eloquent save 方法

如果模型自上一次被取得或保存后没有被做过任何修改,Eloquent 的 save 方法将返回 false

Eloquent Scopes

现在,Eloquent scopes 将遵守 scope 条件中的前导布尔值。例如,如果你用一个 orWhere 条件开始你的 scope,它将不再被转成正常的 where。如果你使用了这一特性(比如在一个循环中添加多个 orWhere 条件),你需要确保第一个条件是正常的 where 来避免布尔值导致的逻辑问题。

如果你的 scopes 使用的第一个条件是 where,不需要做任何修改。你可以用查询构造器的 toSql 方法来验证你的查询语句。

User::where('foo', 'bar')->toSql();

Join 子句

JoinClause 类已经被通过重写来和查询构造器保持一致的语法。on 闭包中可选的 $where 参数现已被移除。如果要添加一个「where」条件,你必须显示地调用 查询构造器 提供的 where 方法:

$query->join('table', function ($join) {
    $join->on('foo', 'bar')->where('bar', 'baz');
});

现在,on 子句的操作符将会被验证并且不能再包含非法值。如果你之前使用了这一特性(比如 $join->on('foo', 'in', DB::raw('("bar")'))),现在需要用适当的 where 子句重写条件:

$join->whereIn('foo', ['bar']);

$bindings 属性同样被移除了。可以用 addBinding 方法来直接操作 join 绑定:

$query->join(DB::raw('('.$subquery->toSql().') table'), function ($join) use ($subquery) {
    $join->addBinding($subquery->getBindings(), 'join');
});

加密

Mcrypt 加密器已被移除

Mycrypt 加密器已经在发行于 2015 年 6 月的 Laravel 5.1.0 中被弃用了。它在 Laravel 5.3.0 中被彻底移除,取而代之的是新的基于 OpenSSL 的加密方案,该方案从 Laravel 5.1.0 开始就已经是默认的加密方案了。

如果你仍然在 config/app.php 配置文件中使用基于 cipher 的 Mycrypt,你需要升级 cipher 到 AES-256-CBC 并且设置你的密钥为 32 字符长的随机字符串,你可以通过 php artisan key:generate 帮你自动生成。

如果你在数据库中使用 Mcrypt 加密器来存储加密后的数据,你可以通过安装 laravel/leagacy-encrypter 来保留 Mcrypt 加密器。你应该使用这个包来解密你的数据,并用新的 OpenSSL 加密器来重新加密。例如,你可以执行像下面的 自定义 Artisan 命令

$legacy = new McryptEncrypter($encryptionKey);

foreach ($records as $record) {
    $record->encrypted = encrypt(
        $legacy->decrypt($record->encrypted)
    );

    $record->save();
}

异常处理器

类构造器

现在,异常处理器的基类需要一个 Illuminate\Container\Container 实例来传递它的构造器。只有当你在 app/Exceptions/Handler.php 文件中使用了 __construct 方法时,这个变更才会影响你的应用程序。如果你使用了该方法,现在需要传递一个容器实例到 parent::__construct 方法:

parent::__construct(app());

未认证的方法

你应该添加 unauthenticated 方法到你的 App\Exceptions\Handler 类中。这个方法会将用户认证异常转成 HTTP 响应:

/**
 * Convert an authentication exception into an unauthenticated response.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  \Illuminate\Auth\AuthenticationException  $exception
 * @return \Illuminate\Http\Response
 */
protected function unauthenticated($request, AuthenticationException $exception)
{
    if ($request->expectsJson()) {
        return response()->json(['error' => 'Unauthenticated.'], 401);
    }

    return redirect()->guest('login');
}

中间件

can 中间件命名空间变更

HTTP Kernel 文件的 $routeMiddleware 属性中的 can 中间件,应该被更新为下面的类:

'can' => \Illuminate\Auth\Middleware\Authorize::class,

can 中间件认证异常

现在,如果用户未被认证 can 中间件会抛出一个 Illuminate\Auth\AuthenticationException 实例。如果你之前是手动去捕获一个其他类型的异常的话,现在需要更新为捕获该异常。大多数情况下,这个变更不会影响你的应用程序。

绑定替代中间件

现在,路由模型绑定使用中间件来实现。所有的应用程序应该添加 Illuminate\Routing\Middleware\SubstituteBindingsapp/Http/Kernel.phpweb 中间件组:

\Illuminate\Routing\Middleware\SubstituteBindings::class,

同时,你应该为绑定替代注册路由中间件到 HTTP kernel 文件的 $routeMiddleware 属性中:

'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,

完成路由中间件注册后,还需把它添加到 api 中间件组:

'api' => [
    'throttle:60,1',
    'bindings',
],

消息通知

安装

Laravel 5.3 包含了一个新的、基于驱动的消息通知系统。首先,你应该向 config/app.php 配置文件的 providers 数组注册 Illuminate\Notifications\NotificationServiceProvider

然后,向 config/app.php 配置文件的 aliases 数组添加 Illuminate\Support\Facades\Notification facade。

最后,在你期望接受消息通知的模型里使用 Illuminate\Notifications\Notifiable trait。

分页

自定义

与之前的 Laravel 5.x 相比,在 Laravel 5.3 中自定义分页器生成的 HTML 变得更加容易。不再需要定义一个「Presenter」,现在你只要定义一个简单的 Blade 模板。自定义分页视图最简单的方法是使用 vendor:publish 命令来导出分页视图到 resources/views/vendor 目录下:

php artisan vendor:publish --tag=laravel-pagination

该命令会把视图放到 resources/views/vendor/pagination 目录下。目录下的 default.balde.php 文件对应默认的分页视图。只需编辑该文件就能修改分页 HTML。

请移步 分页 获取更多信息。

队列

配置

在你的队列配置中,所有的 expire 配置项应该被重命名为 retry_after。同样,Beanstalk 配置文件的 ttr 项也应该被重命名为 retry_after。这一名字的变更让我们更容易理解这个配置项的作用。

闭包

队列闭包不再被支持。如果你正在你的应用程序中使用队列闭包,请把闭包转成一个类,然后把类的实例添加到队列:

dispatch(new ProcessPodcast($podcast));

集合序列化

现在,Illuminate\Queue\SerializesModels trait 能够正确地序列化 Illuminate\Database\Eloquent\Collection 实例。对于绝大多数应用,这个变更不会造成兼容性问题。然而,如果你的应用程序完全依赖于那些不是通过队列任务从数据库重新检索出来的集合的话,你应该验证这一变更不会对你的应用程序造成负面影响。

守护进程

调用 Artisan queue:work 命令时不再需要指定 --daemon 选项。php artisan queue:work 命令默认以守护模式运行。如果你希望任务只被执行一次,可以在命令后面指定 --once 选项:

// Start a daemon queue worker...
php artisan queue:work

// Process a single job...
php artisan queue:work --once

事件数据变更

JobProccessingJobProcessed 这类的队列任务事件不再包含 $data 属性。你应该用 $event->job->payload() 方法来获取事件的数据。

任务表

如果你在 config/queue.php 中使用 database 驱动来存储队列任务,你需要在 jobs 表中删除 jobs_queue_reserved_reserved_at_index 索引,并删除 reserved 列,然后对 queuereserved_at 列添加一个复合索引。

执行失败的任务表

同上,如果使用了 database 驱动,需要在 failed_jobs 表中增加 exception 列,类型为 LONGTEXT。顾名思义,该列将会被用来保存导致任务失败的异常。

序列化模型

通常来说,Laravel 中的队列任务是通过传递一个新的任务实例到 Queue::push 方法来实现的。然而,有些应用可能使用了下面的老旧语法:

Queue::push('ClassName@method');

如果你使用了该语法,队列将不会再自动序列和反序列化 Eloquent 模型。如果你希望 Eloquent 模型仍能被队列自动序列化,那么请添加 Illuminate\Queue\SerializesModels trait 到你的任务类,并使用新的 push 语法:

Queue::push(new ClassName);

路由

资源参数默认为单数形式

在之前的版本中,使用 Route::resource 注册的路由参数未被「单数化」。这会在注册路由模型绑定时导致一些不可预期的行为。例如,给定以下 Route::resource 调用:

Route::resource('photos', 'PhotoController');

该 URI 的 show 路由将被定义为:

/photos/{photos}

在 Laravel 5.3 中,所有的资源路由参数默认都被单数化了。所以,当我们调用 Route::resource 时将注册如下的 URI:

/photos/{photo}

如果你想保持之前的形式,请在 AppServiceProvider 中调用 singularResourceParameters 方法:

use Illuminate\Support\Facades\Route;

Route::singularResourceParameters(false);

资源路由名称不再受前缀影响

对于那些绑定到 Route::resource 的路由名称,URL 前缀不再对其产生影响,因为这一行为违反了优先使用路由名称的目的。

如果你在一个指定 prefix 选项的 Route::group 里使用了 Route::resource,请检查所有的 route helper 和 UrlGenerator::route 调用,确保没有在路由名称前添加 URI 前缀。

如果这一变更导致产生两个相同名称的路由,你有两个选择。要么,在调用 Route::resource 时用 names 选项为路由指定自定义名称。请移步 资源路由文档 或取更多信息。或者,你可以添加 as 选项到路由组:

Route::group(['as' => 'admin.', 'prefix' => 'admin'], function () {
    //
});

验证

表单请求异常

现在,当表单请求验证失败时,Laravel 将抛出一个 Illuminate\Validation\ValidationException 实例来取代之前的 HttpException。如果你曾在代码中手动捕获 HttpException 实例,你现在需要在 catch 语句块中将其更新为 ValidationException

Nullable

当验证数组、布尔值、整形、数字和字符串时,null 将不再被认为是一个合法值,除非规则集里包含了新的 nullable 规则:

Validate::make($request->all(), [
    'field' => 'nullable|max:5',
]);

从 5.1 升级到 5.2.0

估计升级需耗时:少于 1 小时

注: 这里我们会把所有框架中的破坏性变更罗列出来,但并不代表所有的这些变更都会危及你的应用程序。

更新依赖

composer.json 中指定 laravel/framework 5.2.*

增加 "symfony/dom-crawler": "~3.0""symfony/css-selector": "~3.0"composer.json 文件的 require-dev 部分。

用户认证

配置文件

你需要更新配置文件 config/auth.php,内容参照 https://github.com/laravel/laravel/blob/master/config/auth.php

先覆盖最新的配置信息,然后把配置选项修改为你需要的值,如果你还准备使用经典的 Laravel 5.1 基于 Eloquent 的认证体系,大部分选项都应该保持不变。

在新的 auth.php 配置文件中,要特别注意 passwords.users.email 配置项,由于在 Laravel 5.2 对 email 视图路径做了修改,因此要确保该视图路径与应用实际的路径相匹配,如果不匹配的话要更新该配置值。

Contracts

如果你实现了 Illuminate\Contracts\Auth\Authenticatable 契约但没有使用 Authenticatable trait 的话,那么你需要添加一个新的 getAuthIdentifierName 方法到该契约实现类。通常,该方法返回认证实体的主键字段名,如:id

除非你手动实现了此接口,否则这应该影响不到你的应用程序。

自定义驱动

如果你使用了 Auth::extend 自定义获取用户的方法,你现在应该使用 Auth::provider 来自定义用户提供者。一旦你自定义了提供者,就要在新的 auth.php 配置文件中的 providers 数组中配置该提供者。

更多信息,请查看 完整的授权文档.

重定向

loginPath() 方法已从 Illuminate\Foundation\Auth\AuthenticatesUsers 中移除,所以现在没必要在你的 AuthController 控制器中设置 $loginPath 变量。负责授权的 trait 默认情况下会在发生错误时重定向会上一个请求路径。

授权

Illuminate\Auth\Access\UnauthorizedException 被重命名为 Illuminate\Auth\Access\AuthorizationException

如果你之前没有手动捕获该异常,那么这一改变对之前代码没有什么影响。

集合

Eloquent 集合

调用 Eloquent 集合实例的 pluckkeyszipcollapseflattenflip 方法,现在会返回集合基类 Illuminate\Support\Collection

保留键名

slice, chunk, 和 reverse 方法现在会保留集合的键名,如果你不想这些方法保留键名,使用 集合实例 调用 values 方法即可。

Composer 类

Illuminate\Foundation\Composer 类现在被移动到 Illuminate\Support\Composer,如果你没有在代码中使用该类,那么这一改变对程序没有影响。

命令和处理器

自处理命令

在创建定时任务或者命令时不再需要实现 SelfHandling 契约,所有任务现在默认都是自处理的,因此你可以移除该接口。

独立的命令 & 处理器

Laravel 5.2 命令总线模式现在只支持自处理命令,不再支持独立的命令和处理器。

如果你想要继续使用独立的命令和处理器,可以安装提供向后兼容支持的 Laravel Collective 包:https://github.com/LaravelCollective/bus

配置信息

env 环境变量

在配置文件 app.php 中添加 env 配置项,如下:

'env' => env('APP_ENV', 'production'),

缓存和 env 设置项

如果你在开发过程中使用 config:cache 命令,必须 保证只是在配置文件中调用了 env 函数,而不是在应用程序的其它地方。

如果你在应用程序中调用了 env 函数,强烈建议添加适当的配置值到配置文件,然后在该位置调用 env,从而允许你将 env 调用改为 config 调用。

编译文件

请把以下两行从你的 files 数组中移除,如果你的 config/compile.php 文件有出现这两行的话:

realpath(__DIR__.'/../app/Providers/BusServiceProvider.php'),
realpath(__DIR__.'/../app/Providers/ConfigServiceProvider.php'),

不删除的话,可能会在运行 php artisan optimize 的时候触发 service providers listed here do not exist 错误。

CSRF 验证

在单元测试中不再自动进行 CSRF 验证,当然这一改变对你的应用程序代码没什么影响。

数据库

MySQL 日期

自 MySQL 5.7 以后,默认 strict 模式是开启的,所以已经不再支持 0000-00-00 00:00:00 作为默认的日期值。所有的 timestamp 类型的字段在入库的时候都应该是正确的日期格式。

你可以在数据库迁移中使用 useCurrent 方法默认使用当前时间,或者设置字段为 nullable 来接受 null 值:

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

$table->timestamp('foo')->useCurrent();

$table->nullableTimestamps();

MySQL JSON 字段类型

在 MySQL 驱动下,json 字段类型现在创建真实的 JSON 字段类型,如果你没有使用 MySQL 5.7 或者以上版本的话,将无法使用此字段。你可以使用 text 字段类型作为替代。

数据填充

当运行数据库填充时,默认情况下,所有的 Eloquent 数据模型现在都是 unguarded 的,在之前的版本中,你需要手动调用 Model::unguard()

如果你还想在运行数据填充时开启 guard 模式的话,请在 DatabaseSeeder 类的最开始部分调用 Model::reguard()

Eloquent

日期转化

当调用模型或模型集合的 toArray 方法时,任何添加到 $casts 的属性,如 datedatetime,现在都会被转化为字符串。这使在 $dates 数组中制定的日期转化规则保持一致。

全局作用域

我们重写了全局作用域的实现以便于更方便的使用,全局作用域不再需要 remove 方法,因此可以在所有你使用到该方法的地方将其移除。

如果你曾在 Eloquent 查询构建器上调用过了 getQuery 方法以获取底层查询构建器实例,现在应该改为调用 toBase 方法。

如果你因为某种原因直接调用了 remove 方法,需要将其改成 $eloquentBuilder->withoutGlobalScope($scope) 这种方式来调用。

在 Eloquent 查询构建器中新增了 withoutGlobalScopewithoutGlobalScopes 方法,任何调用 $model->removeGlobalScopes($builder) 的地方现在都要改成 $builder->withoutGlobalScopes()

主键

默认情况下,Eloquent 会假设你的主键是 integer 整数类型,并且会强制类型为 integer 整数类型,如果你的主键不是整数类型,请设置类属性 $incrementingfalse

/**
 * 设定主键是否为整数类型
 *
 * @var bool
 */
public $incrementing = true;

事件

核心事件对象

Laravel 的一些核心事件现在使用事件对象取代之前的事件名称以及动态参数,下面是原来的事件名称与现在的事件对象对应关系:

Old New
artisan.start Illuminate\Console\Events\ArtisanStarting
auth.attempting Illuminate\Auth\Events\Attempting
auth.login Illuminate\Auth\Events\Login
auth.logout Illuminate\Auth\Events\Logout
cache.missed Illuminate\Cache\Events\CacheMissed
cache.hit Illuminate\Cache\Events\CacheHit
cache.write Illuminate\Cache\Events\KeyWritten
cache.delete Illuminate\Cache\Events\KeyForgotten
connection.{name}.beginTransaction Illuminate\Database\Events\TransactionBeginning
connection.{name}.committed Illuminate\Database\Events\TransactionCommitted
connection.{name}.rollingBack Illuminate\Database\Events\TransactionRolledBack
illuminate.query Illuminate\Database\Events\QueryExecuted
illuminate.queue.before Illuminate\Queue\Events\JobProcessing
illuminate.queue.after Illuminate\Queue\Events\JobProcessed
illuminate.queue.failed Illuminate\Queue\Events\JobFailed
illuminate.queue.stopping Illuminate\Queue\Events\WorkerStopping
mailer.sending Illuminate\Mail\Events\MessageSending
router.matched Illuminate\Routing\Events\RouteMatched

这些事件对象传入参数和 Laravel 5.1 的事件处理器 完全 一样,例如,如果你在 Laravel 5.1.* 中使用了 DB:listen 事件,在 5.2 中更新代码如下:

DB::listen(function ($event) {
    dump($event->sql);
    dump($event->bindings);
});

你可以去检查每个事件对象类去查看它们的公有属性。

Exception Handling

App\Exceptions\Handler 类的 $dontReport 属性应该被更新为至少包含以下异常:

use Illuminate\Validation\ValidationException;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Symfony\Component\HttpKernel\Exception\HttpException;

/**
 * A list of the exception types that should not be reported.
 *
 * @var array
 */
protected $dontReport = [
    AuthorizationException::class,
    HttpException::class,
    ModelNotFoundException::class,
    ValidationException::class,
];

帮助函数

url() 当你没传参调用时,会返回 Illuminate\Routing\UrlGenerator 实例。

隐式模型绑定

Laravel 5.2 支持「隐式模型绑定」,以便在路由和控制器中基于 URI 标识符自动注入模型实例。然而,这也改变了路由和控制器中类型提示模型实例这一行为。

如果你之前在路由或控制器中类型提示了模型实例,并且希望注入一个空的模型实例,那么现在应该移除这个类型提示,然后在路由或控制器中直接创建一个新的模型实例;否则,Laravel 将会基于路由 URI 的标识符试图从数据库获取一个已存在的模型实例。

IronMQ

IronMQ 队列驱动被移动到自己的扩展包中:

http://github.com/LaravelCollective/iron-queue

Jobs / Queue

php artisan make:job 命令现在默认会创建一个队列任务类,如果你想要创建一个 同步任务(非队列),请在使用该命令时加上 --sync 选项。

邮件

邮件配置中移除了 pretend 选项,取而代之的,使用 log 邮件驱动执行和 pretend 同样的功能,并且 log 驱动能提供更多的邮件相关的信息。

分页

为了与框架生成的其它 URL 保持一致,分页 URL 不再包含斜杠,这一改变对应用代码不产生任何影响。

服务提供者

请在 app.phpproviders 数组中移除以下两个服务提供者:

`Illuminate\Foundation\Providers\ArtisanServiceProvider`
`Illuminate\Routing\ControllerServiceProvider`

Sessions

因为 Laravel 5.2 认证系统更新的原因,所有现存的会话都将失效。

数据库 Session 驱动

我们为框架编写了新的 database Session 驱动,该驱动包含更多的用户信息,例如用户 ID、IP 地址以及用户浏览器信息,如果你想要继续使用之前的 database 驱动,需要在配置文件 session.php 中修改驱动为 legacy-database

如果你想要使用新的驱动,还需要添加 user_id (nullable integer)ip_address (nullable string) 以及 user_agent (text) 字段到存放 Session 的数据表中。

Stringy

框架不再内置 Stringy 库,如果要在应用中使用,你需要通过 Composer 手动安装。

表单验证

异常类型

ValidatesRequests trait 现在会抛出 Illuminate\Foundation\Validation\ValidationException 异常以取代之前的 Illuminate\Http\Exception\HttpResponseException

如果你没有手动捕获该异常,那么这对之前的代码没有影响。

废弃清单

下面这些功能在 Laravel 5.2 中被废弃,在 Laravel 5.3 中会被彻底移除:

  • Illuminate\Contracts\Bus\SelfHandling 契约,现在可以从任务(Job)中移除。
  • 集合的 lists 方法被重命名为 pluck,方法的功能保持一致。
  • 隐式控制器路由注册 Route::controller 被废弃。在路由文件中请使用明确指定的路由注册。此功能很有可能会被整理成扩展包的形式提供。
  • get, post 还有其他的路由辅助函数被废弃,请使用 Route facade 作为替代。
  • Laravel 5.1 的 database session 驱动已经被重命名为 legacy-database,并且将会被移除,请查看上文关于 database session 驱动以获取更多信息.
  • Str::randomBytes 方法被废弃,会被 PHP 原生 random_bytes 取代。
  • Str::equals 方法被废弃,会被 PHP 原生 hash_equals 取代。
  • Illuminate\View\Expression 被废弃,会被 Illuminate\Support\HtmlString 取代。
  • WincacheStore 缓存驱动已被移除。

升级到 5.1.11

Laravel 5.1.11 现支持 授权授权策略。要将这些功能添加到现有的 Laravel 5.1 应用程序中是相当容易的。

注意:这些升级是 可选的,忽略它们并不会影响你的应用程序。

创建 Policies 目录

首先,在你的应用程序创建一个空的 app/Policies 目录。

创建并注册 AuthServiceProvider 与 Gate Facade

在你的 app/Providers 目录创建一个 AuthServiceProvider。你可以 从 GitHub 获取默认的内容,请注意,如果你的应用程序使用自定的命名空间的话,请修改提供者的命名空间。创建完成后,请务必在你的 app.php 配置文件的 providers 数组注册它。

同样的,你必须在你的 app.php 配置文件的 aliases 数组注册 Gate facade:

'Gate' => Illuminate\Support\Facades\Gate::class,

更新用户模型

然后,在你的 App\User 模型使用 Illuminate\Foundation\Auth\Access\Authorizable trait 及 Illuminate\Contracts\Auth\Access\Authorizable contract:

<?php

namespace App;

use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Foundation\Auth\Access\Authorizable;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;

class User extends Model implements AuthenticatableContract,
                                    AuthorizableContract,
                                    CanResetPasswordContract
{
    use Authenticatable, Authorizable, CanResetPassword;
}

更新基础控制器

接着,更新 App\Http\Controllers\Controller 基础控制器,让它使用 Illuminate\Foundation\Auth\Access\AuthorizesRequests trait:

<?php

namespace App\Http\Controllers;

use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;

abstract class Controller extends BaseController
{
    use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
}

升级到 5.1.0

估计升级需耗时:少于 1 小时

更新 bootstrap/autoload.php

bootstrap/autoload.php 里的 $compiledPath 变量按照以下方式更新:

$compiledPath = __DIR__.'/cache/compiled.php';

创建 bootstrap/cache 目录

在你的 bootstrap 目录里,创建一个 cache 目录 (bootstrap/cache)。放置一个有以下内容的 .gitignore 文件在这个目录:

*
!.gitignore

这个目录必须为可写的,框架会暂时存放如 compiled.phproutes.phpconfig.phpservices.json 等文件在此目录。

添加 BroadcastServiceProvider 提供者

在你的 config/app.php 配置文件里面,增加 Illuminate\Broadcasting\BroadcastServiceProviderproviders 数组里。

认证

如果你有使用内置的 AuthController,此控制器使用了 AuthenticatesAndRegistersUsers trait,你会需要对新用户如何创建跟验证做一些修改。

首先,你不再需要传递 GuardRegistrar 实例到基底构造器。你可以从控制器的构造器完全移除这些依赖。

第二,已经不再需要 Laravel 5.0 中使用的 App\Services\Registrar 类。你可以简单的从这个类直接复制你的 validatorcreate 方法粘贴至你的 AuthController。这些方法不需要做其它修改。你必须确定有在你的 AuthController 顶端引入 Validator facade 跟你的 User 模型。

密码控制器

内置的 PasswordController 的构造器不再需要任何依赖。你可以把 5.0 下需要的依赖都移除。

验证

如果你在基底控制器类上重写了 formatValidationErrors 方法,你现在应该把类型提示改成 Illuminate\Contracts\Validation\Validator contract 来取代具体的 Illuminate\Validation\Validator 实例。

同样地,如果你在基底表单请求类上重写了 formatErrors 方法,你现在应该把类型提示改成 Illuminate\Contracts\Validation\Validator contract 来取代具体的 Illuminate\Validation\Validator 实例。

Eloquent

create 方法

Eloquent 的 create 方法现在可以不带任何参数调用。如果你有在自己的模型重写了 create 方法,请把 $attributes 参数的默认值设置成空数组:

public static function create(array $attributes = [])
{
    // 你的自定义实现
}

find 方法

如果你在自己的模型中重写了 find 方法并在方法中调用了 parent::find(),现在则应该把它改成调用 Eloquent 查询语句构造器上的 find 方法:

public static function find($id, $columns = ['*'])
{
    $model = static::query()->find($id, $columns);

    // ...

    return $model;
}

lists 方法

lists 方法现在返回一个 Collection 实例而不是 Eloquent 查找用的一般数组。如果你想要把 Collection 转换成一般数组,请使用 all 方法:

User::lists('id')->all();

请注意查询语句构造器的 lists 方法返回的是一个数组。

日期格式

以前,Eloquent 日期字段的保存格式可以借助重写模型上的 getDateFormat 方法来修改。现在仍然可以这么做。然而,为了方便起见,你可以直接在模型上指定 $dateFormat 属性来取代重写方法。

当序列化模型成 array 或 JSON 时,也会采用该日期格式。当从 Laravel 5.0 迁移到 5.1 时,这可能会改变你的 JSON 序列化的日期字段格式。要想针对序列化模型设置特定的日期格式,你需要在你的模型上重写 serializeDate(DateTime $date) 方法。这个方法可以让你在不改变日期字段保存格式的情况下,精细的控制 Eloquent 序列化格式。

集合类

sort 方法

sort 方法现在会返回全新的集合实例,而不是修改原有的集合:

$collection = $collection->sort($callback);

sortBy 方法

sortBy 方法现在会返回一个全新的集合实例而不会去改动到现有的集合:

$collection = $collection->sortBy('name');

groupBy 方法

groupBy 方法现在会返回 Collection 实例给父 Collection 的每一个元素。如果你想要把所有元素转换回一般数组,你可以通过 map 来处理:

$collection->groupBy('type')->map(function($item)
{
    return $item->all();
});

lists 方法

lists 方法现在返回一个 Collection 实例而不是一个一般数组。如果你想要把 Collection 转换成一般数组,请使用 all 方法:

$collection->lists('id')->all();

命令和处理进程

app/Commands 目录已经被改名成 app/Jobs。然而你并不需要把所有的命令移动到新的位置,且可以继续用 make:commandhandler:command Artisan 命令来生成类。

app/Handlers 目录已经被改名成 app/Listeners 并且现在只包含事件监听者。不需要移动或重命名现有的命令和事件处理进程,并且可以继续使用 handler:event 命令来生成事件处理进程。

借由 Laravel 5.0 目录结构提供的向下兼容性,你可以先升级你的应用程序到 Laravel 5.1,然后在你或你的团队方便的时候再慢慢地将你的事件跟命令升级到它们的新位置上。

Blade

createMatchercreateOpenMatchercreatePlainMatcher 方法已经从 Blade 编译器移除。在 Laravel 5.1,请使用新的 directive 方法来创建自定义的 Blade 标签。请查看 扩展 blade 文档来了解更多信息。

测试

添加 protected $baseUrl 属性到 tests/TestCase.php 文件中:

protected $baseUrl = 'http://localhost';

语言包

第三方扩展包发布语言包的默认目录已经改变。必须从 resources/lang/packages/{locale}/{namespace} 移动所有的第三方扩展包语言包到 resources/lang/vendor/{namespace}/{locale} 目录。例如,Acme/Anvil 扩展包命名空间为 acme/anvil::foo 的英文语言包应该从 resources/lang/packages/en/acme/anvil/foo.php 移动到 resources/lang/vendor/acme/anvil/en/foo.php

Amazon 网络服务 SDK

如果你有使用 AWS SQS 队列驱动或 AWS SES 电子邮件驱动,你应该升级你安装的 AWS PHP SDK 到 3.0 版本。

如果你有使用 Amazon S3 文件系统驱动,你将需要借助 Composer 更新对应的文件系统扩展包:

  • Amazon S3: league/flysystem-aws-s3-v3 ~1.0

弃用的功能

以下的 Laravel 功能已经被弃用, 并将会在 2015 十二月发布的 Laravel 5.2 中被完全移除:

  • 路由过滤器已经被弃用,转而使用中间件
  • Illuminate\Contracts\Routing\Middleware contract 已经被弃用。你的中间件上不需要任何 contract。此外,TerminableMiddleware contract 也已经被弃用。不要实现接口,简单地定义一个 terminate 方法在你的中间件上就好。
  • Illuminate\Contracts\Queue\ShouldBeQueued contract 已经被弃用而用 Illuminate\Contracts\Queue\ShouldQueue 取代。
  • Iron.io 的「推送队列」已经被弃用而用一般的 Iron.io 队列和队列监听者取代。
  • Illuminate\Foundation\Bus\DispatchesCommands trait 已经被弃用并改名成 Illuminate\Foundation\Bus\DispatchesJobs
  • Illuminate\Container\BindingResolutionException 被移到 Illuminate\Contracts\Container\BindingResolutionException
  • 服务容器的 bindShared 方法已经被弃用,转而使用 singleton 方法取代。
  • Eloquent 和查询语句构造器的 pluck 方法已被弃用并改名为 value
  • 集合的 fetch 方法已经被弃用,转而用 pluck 方法取代。
  • array_fetch 辅助函数已经被弃用,转而用 array_pluck 方法取代。

升级到 5.0.16

在你的 bootstrap/autoload.php 文件中,更新 $compiledPath 变量为:

$compiledPath = __DIR__.'/../vendor/compiled.php';

从 4.2 升级到 5.0

全新安装,然后迁移

推荐的升级方式是创建一个全新的 Laravel 5.0 项目,然后复制你 4.2 网站特定的应用程序文件到此新的应用程序。其中包含控制器、路由、Eloquent 模型、Artisan 命令、资源文件,和其它专属于你的程序代码。

开始前,请先在你的本地环境中 安装一个新的 Laravel 5 应用程序 到一个全新的目录中。不要安装超过 5.0 的任何版本,因为我们需要先完成迁移至 5.0 的步骤。我们将会在后面详细探讨各部分的详细迁移过程。

Composer 依赖与扩展包

别忘了复制其它额外的 Composer 依赖扩展包到你的 5.0 应用程序内。其中包含如 SDKs 的第三方代码。

部分 Laravel 专用扩展包也许不兼容于刚发布的 Laravel 5。请向扩展包的维护者确认该扩展包支持 Laravel 5 的版本。在你添加完应用程序需要的所有额外 Composer 依赖后,请运行 composer update

命名空间

默认情况下,Laravel 4 应用程序不会在应用程序的代码中使用命名空间。如所有的 Eloquent 模型和控制器都简单地存在于「全局」的命名空间中。为了更快速的迁移,Laravel 5 也允许你将这些类继续保留在全局的命名空间内。

配置

迁移环境变量

复制新的 .env.example 文件到 .env,在 5.0 中这相当于原本的 .env.php。在此设置合适的值,如 APP_ENVAPP_KEY (你的加密密钥)、数据库凭证、缓存驱动与 session 驱动。

此外,将你原本的 .env.php 文件中自定义的设置值都复制并移到 .env (本机环境的实际设置值) 和 .env.example (给其他团队成员的范本文件)。

更多关于环境配置的信息,请查看 完整文档

注意:在部署你的 Laravel 5 应用程序之前,你需要先在正式主机上放置 .env 文件并给其设置好适当的值。

配置文件

Laravel 5.0 不再使用 app/config/{environmentName}/ 目录结构来为指定环境提供配置文件。取而代之的是,将环境对应的各种设置值移到 .env,并接着借助 env('key', 'default value') 来获取配置文件的值。你可以在 config/database.php 配置文件中看到相关例子。

将配置文件放在 config/ 目录下,来代表所有环境共用的配置文件,或是在使用 env() 来获取对应该环境的设置值。

请记住,如果你添加了其它的键值到 .env 文件中,记得在 .env.example 文件内也要添加相对应的键值。这将可以帮助其他团队成员创建他们自己的 .env 文件。

路由

复制粘贴你原本的 routes.php 文件到 app/Http/routes.php

控制器

下一步,将你所有的控制器移到 app/Http/Controllers 目录下。因为在本指南中我们不打算迁移到完整的命名空间,请将 app/Http/Controllers 目录添加到 composer.jsonclassmap 属性中。接下来,你可以从 app/Http/Controllers/Controller.php 基底抽象类中移除命名空间。请确认你迁移过来的控制器都继承这个基类。

在你的 app/Providers/RouteServiceProvider.php 文件,设置 namespace 属性为 null

路由过滤器

将过滤器逻辑绑定从 app/filters.php 复制到 app/Providers/RouteServiceProvider.phpboot() 方法。并在 app/Providers/RouteServiceProvider.php 添加 use Illuminate\Support\Facades\Route; 来继续使用 Route Facade。

你不需要移动任何 Laravel 4.0 中的默认过滤器,如 authcsrf。他们已经内置其中,只是换作以中间件形式出现。那些在路由或控制器内有使用到旧有默认过滤器的 (例如,['before' => 'auth']) 请修改使用新的中间件 (例如,['middleware' => 'auth'])。

过滤器在 Laravel 5 中没有被移除。你仍然可以绑定并借由 beforeafter 使用你自己自定义的过滤器。

全局 CSRF

默认情况下,所有路由都会启用 CSRF 保护。如果你想要关闭它们或是只想在特定路由手动开启,请从 App\Http\Kernelmiddleware 数组移除这行:

'App\Http\Middleware\VerifyCsrfToken',

如果你想要在其它地方使用它,添加此行到 $routeMiddleware

'csrf' => 'App\Http\Middleware\VerifyCsrfToken',

现在你可以在路由内使用 ['middleware' => 'csrf'] 添加中间件到各个路由/控制器上。想要了解更多关于中间件的信息,请查看 完整文档

Eloquent 模型

你可以随意创建一个新的 app/Models 目录来放置 Eloquent 模型。同样地,这个目录必须添加到 composer.json 文件的 classmap 属性中。

将正在使用 SoftDeletingTrait 的模型更改为使用 Illuminate\Database\Eloquent\SoftDeletes

Eloquent 缓存

Eloquent 不再提供 remember 方法来缓存查找结果。现在你有责任手动地使用 Cache::remember 方法缓存查找结果。要了解更多关于缓存的信息,请查看 完整文档

用户认证模型

要使用 Laravel 5 的认证系统,请遵循以下指引来升级你的 User 模型:

从你的 use 区块删除以下内容:

use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;

添加以下内容到你的 use 区块:

use Illuminate\Auth\Authenticatable;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;

移除 UserInterface 和 RemindableInterface 接口。

标记类实现以下接口:

implements AuthenticatableContract, CanResetPasswordContract

在类声明引入以下 traits:

use Authenticatable, CanResetPassword;

如果你有使用它们,请把 Illuminate\Auth\Reminders\RemindableTraitIlluminate\Auth\UserTrait 从你的 use 区块和类声明中移除。

Cashier 的用户需要做的修改

Laravel Cashier 使用的 trait 和接口名称已作修改。trait 请改用 Laravel\Cashier\Billable 取代 BillableTrait。接口实现请用 Laravel\Cashier\Contracts\Billable 取代 Laravel\Cashier\BillableInterface。不需要修改其它任何方法。

Artisan 命令

将所有的命令类从原本的 app/commands 目录移到新的 app/Console/Commands 目录。接下来,把 app/Console/Commands 目录添加到 composer.json 文件的 classmap 属性中。

然后,把 Artisan 命令清单从 start/artisan.php 复制到 app/Console/Kernel.php 文件里的 command 数组中。

数据库迁移和数据填充

因为数据库里应该已经有 users 表了,请删除 Laravel 5.0 内置的两个迁移文件。

将所有的迁移文件从原本的 app/database/migrations 目录移到新的 database/migrations。所有的数据填充档也应该从 app/database/seeds 移到 database/seeds

全局 IoC 绑定

如果你在 start/global.php 有任何的 服务容器 绑定,请将它们全部移至 app/Providers/AppServiceProvider.php 文件的 register 方法。你可能需要引入 App facade。

你也可以选择将这些绑定,依照类拆分到各别的服务提供者中。

视图

将旧视图从 app/views 移到新的 resources/views 目录。

Blade 标签修改

基于安全考量,Laravel 5.0 会把所有 {{ }}{{{ }}} Blade 标签的输出的特殊字符都进行转译。新的 {!! !!} 标签则被采用来显示原始未转译的输出。当你 有足够把握 来保证显示的原始输出内容是安全的,那么升级你的应用程序的最安全方法是只使用新的 {!! !!} 标签。

然而,如果你 必须 使用旧的 Blade 语法,请在 AppServiceProvider@register 的结尾加入以下几行:

\Blade::setRawTags('{{', '}}');
\Blade::setContentTags('{{{', '}}}');
\Blade::setEscapedContentTags('{{{', '}}}');

上述设置你不该轻易使用,这将使你的应用程序更加容易遭受 XSS 攻击。而且用 {{-- 注释将无法作用。

语言包

将你的语言包从 app/lang 移到新的 resources/lang 目录。

public 目录

从你的 4.2 应用程序的 public 目录内复制公开的 assets 到新应用程序的 public 目录内。请确定有保留 5.0 版本的 index.php

测试

将你的测试从 app/tests 移到新的 tests 目录。

杂项文件

复制项目内任何其它的文件,例如: .scrutinizer.yml, bower.json 以及其它类似的工具配置文件。

你可以将 Sass、Less 或 CoffeeScript 移动到任何你想放置的地方。resources/assets 目录是一个不错的默认位置。

表单和 HTML 辅助函数

如果你使用表单或 HTML 辅助函数,你将会看到 class 'Form' not foundclass 'Html' not found 的错误。表单和 HTML 辅助函数已经在 Laravel 5.0 中被弃用。然而,有些社区导向的替代品可供替代,例如:Laravel Collective 维护的这些。

举例来说,你可以把 "laravelcollective/html": "~5.0" 添加到你的 composer.jsonrequire 区块。

你也需要表单和 HTML 的 facades 以及服务提供者。编辑 config/app.php 并添加这行到 'providers' 数组内:

'Collective\Html\HtmlServiceProvider',

接着,添加这几行到 'aliases' 数组内:

'Form' => 'Collective\Html\FormFacade',
'Html' => 'Collective\Html\HtmlFacade',

缓存管理员

如果你的代码有注入 Illuminate\Cache\CacheManager 来获取非 Facade 版本的 Laravel 缓存,请改成注入 Illuminate\Contracts\Cache\Repository 取代。

分页

替换所有的 $paginator->links()$paginator->render()

依次替换所有的 $paginator->getFrom()$paginator->getTo()$paginator->firstItem()$paginator->lastItem()

$paginator->getPerPage()$paginator->getCurrentPage()$paginator->getLastPage()$paginator->getTotal() 移除「get」前缀 (例如:$paginator->perPage())。

Beanstalk 队列

Laravel 5.0 现在需要 "pda/pheanstalk": "~3.0" 取代原本的 "pda/pheanstalk": "~2.1"

Remote

Remote 组件已被弃用。

Workbench

Workbench 组件已被弃用。

从 4.1 升级到 4.2

PHP 5.4+

Laravel 4.2 需要 PHP 5.4.0 或更高的版本。

默认加密

在你的 app/config/app.php 配置文件中添加一个新的 cipher 选项。这个选项的值应该为 MCRYPT_RIJNDAEL_256

'cipher' => MCRYPT_RIJNDAEL_256

这个设置可以被用来调整 Laravel 加密工具使用的默认加密方法。

注意:在 Laravel 4.2,默认的加密方法为 MCRYPT_RIJNDAEL_128 (AES),它认为是最安全的加密方法。必须将加密方法改回 MCRYPT_RIJNDAEL_256 来解密在 Laravel 4.1 以前版本下加密的 cookies 和值。

现在在可以软删除的模型上使用 Traits

如果你有使用可以软删除的模型,softDeletes 属性已经被移除。现在你必须使用 SoftDeletingTrait 如下:

use Illuminate\Database\Eloquent\SoftDeletingTrait;

class User extends Eloquent
{
    use SoftDeletingTrait;
}

你也必须手动地添加 deleted_at 字段到你的 dates 属性中:

class User extends Eloquent
{
    use SoftDeletingTrait;

    protected $dates = ['deleted_at'];
}

而所有软删除的 API 使用方式保持不变。

注意:SoftDeletingTrait 无法在模型基类下被使用。他必须用在一个实际的模型类。

视图 / 分页的环境名称修改

如果你直接参照 Illuminate\View\EnvironmentIlluminate\Pagination\Environment 类, 请更新你的代码将其改为参照 Illuminate\View\FactoryIlluminate\Pagination\Factory。改名后的这两个类更可以代表他们的功能。

额外的参数 On Pagination Presenter

如果你扩展了 Illuminate\Pagination\Presenter 类,抽象方法 getPageLinkWrapper 的参数表变成要加上 rel 参数:

abstract public function getPageLinkWrapper($url, $page, $rel = null);

Iron.Io 队列加密

如果你有使用 Iron.io 队列驱动,你需要添加一个新的 encrypt 选项到你的 queue 配置文件中:

'encrypt' => true

从 4.1.x 以前版本升级到 4.1.29

Laravel 4.1.29 对于所有的数据库驱动加强了 column quoting 的部分。当你的模型中 没有 使用 fillable 属性时,他保护你的应用程序不会受到 mass assignment 漏洞影响。如果你在模型中使用 fillable 属性来防范 mass assignment,你的应用程序将不会有漏洞。然而,如果你使用 guarded 并传递用户控制的数组到「更新」或「保存」类型的函数中,那你应该立即升级到 4.1.29 以避免你的应用程序遭受 mass assignment 的风险。

要升级到 Laravel 4.1.29,只要 composer update 即可。在这个发行版本中没有重大的更新。

从 4.1.25 以前版本升级到 4.1.26

Laravel 4.1.26 针对「记得我」cookies 的安全性进行了更新。在此更新之前,如果一个 「记得我」cookie 被恶意用户劫持,该 cookie 在很长一段时间内仍然有效,即便真实的用户进行了重设密码或者注销等操作。

此更动需要在你的 users (或同等的) 数据表中添加一个额外的 remember_token 字段。在更新之后,当用户每次登录你的应用程序将会被给予一个全新的 token。在用户注销应用程序后,这个 token 也会被更新。这个更新的影响为:如果一个「记得我」的 cookie 被劫持,只要用户注销应用程序该 cookie 将会失效。

升级路径

首先,添加一个新的 remember_token 字段到你的 users 数据表中,它可为空值且为 VARCHAR(100)、TEXT 或同等的类型。

然后,如果你是使用 Eloquent 认证驱动,请更新你的 User 类的以下三个方法:

public function getRememberToken()
{
    return $this->remember_token;
}

public function setRememberToken($value)
{
    $this->remember_token = $value;
}

public function getRememberTokenName()
{
    return 'remember_token';
}

注意:所有现存的「记得我」sessions 在此更新后将会失效,所以应用程序的所有用户将会被迫重新认证。

扩展包维护者

Illuminate\Auth\UserProviderInterface 接口加了两个新的方法。简单的实现可以在默认驱动中找到:

public function retrieveByToken($identifier, $token);

public function updateRememberToken(UserInterface $user, $token);

Illuminate\Auth\UserInterface 也添加了三个新方法并被描述在「升级路径」部分。

从 4.0 升级到 4.1

升级你的 Composer 依赖

要将你的应用程序升级至 Laravel 4.1,则必须将应用程序的 composer.json 里的 laravel/framework 版本更改至 4.1.*

文件替换

将你的 public/index.php 文件替换为 这个从 repository 复制的全新文件

将你的 artisan 文件替换为 这个从 repository 复制的全新文件

添加配置文件及选项

更新 app/config/app.php 配置文件里的 aliasesproviders 数组。这些数组更新后的值可以在 这个文件中找到。请确保你自定义的 providers / aliases 和扩展包的 providers / aliases 都已添加回数组中。

从 repository 添加新的 app/config/remote.php 文件。

在你的 app/config/session.php 文件里,添加新的 expire_on_close 设置选项。默认值应该为 false

在你的 app/config/queue.php 文件里,添加新的 failed 设置区块。以下为这区块的默认值:

'failed' => [
    'database' => 'mysql', 'table' => 'failed_jobs',
],

(可选的) 在你的 app/config/view.php 文件里,将 pagination 设置选项更新为 pagination::slider-3

控制器的修改

如果 app/controllers/BaseController.php 有个 use 语句在最上面,将 use Illuminate\Routing\Controllers\Controller; 改为 use Illuminate\Routing\Controller;

密码提醒的修改

密码提醒功能在大幅改进后已经具有更好的灵活性。你可以运行 php artisan auth:reminders-controller Artisan 命令来检查新的存根控制器。你也可以浏览 更新后的文档 来相应更新你的应用程序。

更新你的 app/lang/en/reminders.php 语言文件来对应 这个新版文件

环境侦测的修改

为了安全因素,不再使用网址域名来侦测应用程序的环境。因为这些值很容易被伪造欺骗,继而让攻击者通过请求来修改环境。你必须改为使用机器的主机名称 (在 Mac、Linux 和 Windows 下运行 hostname 命令的值) 来侦测环境。

更简单的日志文件

Laravel 目前只会生成单个的日志文件:app/storage/logs/laravel.log。然而,你还是可以在 app/start/global.php 文件设置更改它的行为。

移除重定向向结尾的斜线

在你的 bootstrap/start.php 文件中,移除对 $app->redirectIfTrailingSlash() 的调用。这个方法已经不再需要,因为这个功能现在已交由框架内的 .htaccess 文件来处理。

然后,用 新的文件 替换为 Apache 的 .htaccess,来处理结尾的斜线。

获取目前路由

现在通过 Route::current() 获取当前路由,而不是 Route::getCurrentRoute()

Composer 更新

一旦你完成以上更新,则可以运行 composer update 功能来更新应用程序的核心文件!如果发生 class load 错误,试着运行 update 命令并加上 --no-scripts 选项,样就像这样:composer update --no-scripts

通配符事件监听者

通配符事件监听者不再添加事件到你的处理函数参数上。如果你需要寻找触发的事件,则可用 Event::firing() 来触发。


{note} 欢迎任何形式的转载,但请务必注明出处,尊重他人劳动共创开源社区。

转载请注明:本文档由 Laravel China 社区 [laravel-china.org] 组织翻译,详见 翻译召集帖

文档永久地址: http://d.laravel-china.org