从 5.2.0 升级到 5.3.0
预计升级时间:2 – 3 小时
PHP & HHVM
Laravel 5.3 需要 PHP 5.6.4 或更高的版本,HHVM 将不再做官方支持,因为它与 PHP 5.6+ 并不是包含完全相同的特性。
数组
Key / Value 顺序做了更改
Arr 类的 first, last, contains 方法回调函数的第一个参数现在需要传 ‘value’。例如:
Arr::first(function ($value, $key) {
return ! is_null($value);
});在 Laravel 上一个版本中,$key 是第一个传递的。由于大多数使用情况中只会关心 $value ,所以现在它作为第一个参数。你需要在应用中对这三个方法做一个全局搜索,以核对 $value 是否是作为回调函数的第一个参数传递的。
Artisan
make:console 命令
make:console 重命名为了 make:command
用户认证
Authentication 脚手架
框架中默认提供的两个用户认证控制器分成了四个小的控制器。这个变更提供了更加简洁、清晰的用户认证控制器。把你的应用升级到新的用户认证的最简单的方式是从 Github 上获取最新的拷贝并放置到你的应用中。
你还需要确保在应用中的 routes.php 文件中调用 Route::auth() 方法,这个方法会为新的用户认证注册合适的路由。
当这些控制器放到你的应用中后,你需要重新实现你对这些控制器做的修改。例如,你修改过用户认证的 guard,那你可能需要重写控制器的 guard 方法,你可以检查每一个用户认证控制器的 trait 来决定覆盖哪些方法。
routes.php 文件中是否有调用 Route::auth 方法。密码重置邮件
密码重置邮件现在使用新的 Laravel 通知功能。当发送密码重置链接的时候,如果你想定制发送的通知,你可以覆盖 Illuminate\Auth\Passwords\CanResetPassword trait 的 sendPasswordResetNotification 方法。
你的 User 模型必须 use 新的 Illuminate\Notifications\Notifiable trait 以确保密码重置链接邮件可以成功发送。
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
}config/app.php 配置文件的 providers 数组中注册 Illuminate\Notifications\NotificationServiceProvider。Logout 使用 POST 方法
Route::auth 方法会为 /logout 注册一个 POST 路由而非 GET 路由。这可以组织其他 WEB 应用能够登出你的应用的用户。升级的话,你或者更改你的登出请求使用 POST 方法,或者为 /logout URI 注册一个你自己的 GET 路由。
Route::get('/logout', 'Auth\LoginController@logout');用户授权
使用 Class 名称调用 Policy 方法
一些 policy 方法只接受当前认证的用户,而非他们授权的模型的实例。最常见的是认证 create 方法。例如,当你发布一篇博客的时候,你可能希望检查这个用户是否具有发布博客的权限。
当定义不接受模型实例的 policy 方法的时候,例如 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 中,包围在传递给回调函数的 $expression 外的大括号已经取消了。请查看 Blade 扩展 文档,并检查你定义的 Blade 指令是否还能正常使用。
// Laravel 5.2
Blade::directive('datetime', function($expression) {
return "<?php echo with{$expression}->format('m/d/Y H:i'); ?>";
});
// Laravel 5.3
Blade::directive('datetime', function($expression) {
return "<?php echo $expression->format('m/d/Y H:i'); ?>";
});
缓存
扩展闭包绑定了 $this
当使用闭包调用 Cache::extend 方法的时候,$this 会绑定到 CacheManager 实例,允许你在闭包中调用它的方法:
Cache::extend('memcached', function ($app, $config) {
try {
return $this->createMemcachedDriver($config);
} catch (Exception $e) {
return $this->createNullDriver($config);
}
});集合
Key / Value 顺序变更
first, last, contains 集合方法使用 value 作为回调函数的第一个参数,例如:
$collection->first(function ($value, $key) {
return ! is_null($value);
});在上一个版本的 Laravel 中,$key 是第一个参数。由于大多数使用情况中只关注 $value,它现在作为第一个参数传递。你需要在应用中对这三个方法做一个全局查找,检查 $value 是否是作为第一个参数传递的。
where 比较现在默认为宽松的
where 方法现在默认提供了一种宽松的比较而非严格比较,如果你要做一个严格比较的话,你可以使用 whereStrict 方法。
where 方法现在已经不再接受第三个参数来指定是否是“严格的”。你需要根据应用的需要明确指定调用 where 或 whereStrict 方法。
数据库
集合
Query Builder 现在返回一个 Illuminate\Support\Collection 实例而非数组。这确保了 Query Builder 与 Eloquent 返回结果的一致性。
如果你不想把 Query Builder 查询结果合并为 Collection 实例,你可以在 Query Builder 的 get 方法后连接一个 all 方法。这将返回一个纯 PHP 的数组,允许你向后兼容维护。
$users = DB::table('users')->get()->all();Eloquent $morphClass 属性
Eloquent 模型中可以定义的 $morphClass 属性已经被移除,被 “morph map” 取代。定义 morph map 可以为预加载提供支持,并解决了多态关系中额外的 BUG。如果你之前依赖 $morphClass 属性的话,可以使用下面的语法迁移到 morphMap :
Relation::morphMap([
'YourCustomMorphName' => YourModel::class,
]);例如,你之前定义了下面的 $morphClass 属性:
class User extends Model
{
protected $morphClass = 'user'
}你需要在 AppServiceProvider 的 boot 方法中定义下面的 morphMap :
use Illuminate\Database\Eloquent\Relation;
Relation::morphMap([
'user' => User::class,
]);Eloquent 的 save 方法
现在,当模型没有更改的话,save 方法将返回 false。
Eloquent scopes
Eloquent scopes 现在优先考虑布尔值的 scope 约束。例如,当你的 scope 以 orWhere 约束开始的话,它将不再转换为 where 。如果你依赖这个功能(例如,在一个循环中添加多个 orWhere 条件),你需要核实第一个条件是普通的 where 以避免任何布尔逻辑问题。
如果你的 scope 以 where 开始,则不需要进行任何修改。记得,你可以通过 toSql 方法来查看查询语句:
User::where('foo', 'bar')->toSql();Join 闭包
JoinClause 类已经重写,以统一与 Query Builder 的语法。on 闭包函数中可选的 $where 参数已经取消。要添加 where 条件的话,你可以使用 Query Builder 提供的 where 方法:
$query->join('table', function($join) {
$join->on('foo', 'bar')->where('bar', 'baz');
});$bindings 属性也被移除了。想要使用 join 绑定的话,你可以直接使用 addBinding 方法:
$query->join(DB::raw('('.$subquery->toSql().') table'), function($join) use ($subquery) {
$join->addBinding($subquery->getBindings(), 'join');
});加密
Mcrypt encrypter 已经移除
2015 年 6 月发布 Laravel 5.1.0 的时候就已经弃用,在 5.3.0 中已经完全移除了,取而代之的是基于 OpenSSL 的新的算法实现,它自 Laravel 5.1.0 之后就一直作为默认的算法。
如果在 config/app.php 文件中你还在使用基于 cipher 的算法,你需要把它更改为 AES-256-CBC ,并把 key 设置为 32 位的随机字符串,可以通过 php artisan key:generate 来生成。
如果你已经在数据库中存储着 Mcrypt encrypter 的加密结果,你可以安装 laravel/legacy-encrypter 包,它包含了遗留的 Mcrypt encrypter 实现。你应该使用这个包解密加密过的数据,并重新使用新的 OpenSSL 算法加密。例如你可以在自定义 Artisan 命令中像下面这样做:
$legacy = new McryptEncrypter($encryptionKey);
foreach ($records as $record) {
$record->encrypted = encrypt(
$legacy->decrypt($record->encrypted)
);
$record->save();
}异常处理
构造函数
默认的异常处理现在需要给构造函数传递一个 Illuminate\Container\Container 实例。这个更改只会在你的应用的 app/Exception/Handler.php 文件中定义了 __construct 方法的时候受影响。如果你这么做了,你需要给 parent::__construct 方法传递一个 container 实例:
parent::__construct(app());
中间件
can 中间件的命名空间修改
在 HTTP kernel 中列出的 $routeMiddleware 属性中的 can 中间件需要更改为下面的类:
'can' => \Illuminate\Auth\Middleware\Authorize::class,
can 中间件认证异常
现在当用户未认证的时候,can 中间件会抛出一个 Illuminate\Auth\AuthenticationException 实例。你需要更改程序捕获该异常。多数情况下,这个更改不会影响你的应用程序。
绑定 Substitution 中间件
路由模型绑定现在支持使用中间件。所有应用现在都需要给 app/Http/Kernel.php 文件中的 web 中间件组添加 Illuminate\Routing\Middleware\SubstituteBindings 中间件。
\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 。并且需要在 alias 数组中添加 Illuminate\Support\Facades\Notification Facade。最后你可以在 User 模型或其他需要接收通知的模型中使用 Illuminate\Notifications\Notifiable trait。
分页
自定义
Laravel 5.3 与之前的 Laravel 5.x 版本相比,自定义分页生成的 HTML 更加容易了。你只需定义一个 Blade 模板即可,而不在需要定义 Presenter 类了。最简单的方法是通过 vendor:publish 命令把它们导出到 resources/views/vendor 目录:
php artisan vendor:publish --tag=laravel-pagination
这个命令会把视图放到 resources/views/vendor/pagination 文件夹中。文件夹中的 default.blade.php 对应的是默认的分页视图。只需编辑这个文件更改生成的分页 HTML。
请查看 分页 文档来获取更多内容。
队列
配置
在队列配置文件中,所有的 expire 配置项都要重命名为 retry_after 。同样的,Beanstalk 配置的 ttr 也需要重命名为 retry_after 。这个更改为配置项提供了更加清晰的目的。
闭包
队列闭包现在已经不再支持。如果你的应用使用闭包处理队列,你需要把闭包转换为一个类,并处理这个类的实例。
集合序列化
Illuminate\Queue\SerializesModels trait 现在可以正确的序列化 Illuminate\Database\Eloquent\Collection 的实例。对于大多数应用来说,这并不是一个破坏性的更改。但是如果你的应用依赖于不是通过 queued job 获取的数据集的 collections,那你应该核对下这个更改是否影响你的应用。
后台驻留任务
当调用 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
事件数据更改
各种队列任务事件如 JobProcessing 和 JobProcessed 不再包含 $data 属性。你需要更新应用调用 $event->job->payload() 方法来获取相应的数据。
失败任务表
你的应用有个 failed_jobs 表,你需要为表添加一个 exception 列,exception 应该是 TEXT 类型的,用于存储导致任务失败的相应的字符串。
在遗留的队列任务中序列化模型
一般情况下,Laravel 的任务是通过给 Queue::push 传递一个任务实例实现队列化,然而,有些应用可能使用下面遗留的语法来序列化任务:
Queue::push('ClassName@method');如果你使用这个语法来序列化任务,Eloquent 模型将不再自动序列化,并在队列中重新取回。如果你希望 Eloquent 模型在队列中自动序列化,你需要在任务类中使用 Illuminate\Queue\SerializesModels trait,并使用新的 push 语法队列化任务:
Queue::push(new ClassName);
路由
resource 参数将默认为单数
在上一个 Laravel 版本中,使用 Route::resource 注册的路由是非单数的。这在路由模型绑定中可能会导致一些意想不到的行为。例如,给定下面的 Route::resource 调用:
Route::resource('photos', 'PhotoController');show 的 URI 将定义为下面这样:
/photos/{photos}在 Laravel 5.3 中,所有的参数都将默认为单数。因此,相同的 Route::resource 调用将注册下面的 URI:
/photos/{photo}如果你想维持之前的行为,而非把 resource 路由参数转为单数,你可以在 AppServiceProvider 中调用 singularResourceParameters 方法:
use Illuminate\Support\Facades\Route; Route::singularResourceParameters(false);
resource 路由名称将不再受前缀影响
当使用 Route::resource 时,URL 前缀将不再影响分配的路由名称,因为这个行为会导致希望使用路由名称为第一位的目的失败。
如果你的应用在指定了 prefix 的 Route::group 中调用 Route::resource,你需要检查所有调用 route 辅助方法的地方,确保已经不再在路由名称前添加 prefix URI。
如果这个更改导致你有两个路由使用相同的名称,当调用 Route::resource 的时候你可以使用 names 选项来给一个指定的路由定义名称。参考 resource 路由 获取更多内容。
验证
Form Request 异常
如果表的请求验证失败,Laravel 现在回抛出一个 Illuminate\Validation\ValidationException 实例而非 HttpException 实例。如果你手动捕获有表单请求抛出的 HttpException 实例,你需要更新 catch 代码块来捕获 ValidationException 异常。
原始的 Nullable
当验证数组、布尔、整型、数字、以及字符串的时候, null 将不再作为一个正确的值,除非指定了新的 nullable 规则:
Validate::make($request->all(), [
'string' => 'nullable|max:5',
]);该篇属于专题:《Laravel 5.3 中文文档》
- 下一篇: 《「Laravel 5.3 中文文档」开始 – 安装》
php 2016/08/21 17:44
赞,laravel又升级了,要求php5.6+,可惜现在还在用5.0.。。。
Specs 2016/08/21 19:15
@ 都这个年代了,还用 5.0 啊。。人家很多都在用 7.0 了~