# 序言 —— 升级指南 ## 更新到 5.1.11 Laravel 5.1.11包含了对授权和策略的支持,将这些新特性整合到已经存在的Laravel 5.1中很简单。 > 注意:这些更新是可选的,忽略它们并不影响你的应用。 ### 创建策略类目录 首先,在应用中创建一个空的`app/Policies`目录。 ### 创建/注册AuthServiceProvider & Gate门面 在`app/Providers`目录下创建`AuthServiceProvider`,你可以从[GitHub](https://raw.githubusercontent.com/laravel/laravel/master/app/Providers/AuthServiceProvider.php)上拷贝该默认提供者的内容,创建完成后,确保在配置文件`app.php`的`providers`数组中注册该提供者。 此外,还要在配置文件`app.php`的`aliases`数组中注册`Gate`[门面](http://laravelacademy.org/post/97.html): ~~~ 'Gate' => Illuminate\Support\Facades\Gate::class, ~~~ ### 更新User模型 然后,在`App\User` 模型中使用 `Illuminate\Foundation\Auth\Access\Authorizable` trait并实现`Illuminate\Contracts\Auth\Access\Authorizable`契约: ~~~ <?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`中的变量$compilePath: ~~~ $compiledPath = __DIR__.'/cache/compiled.php'; ~~~ ### 创建bootstrap/cache目录 在`bootstrap`目录中,创建`cache`目录,在该目录中创建一个`.gitignore`文件,编辑文件内容如下: ~~~ *!.gitignore ~~~ 该目录应该是可写的,用来存储临时优化文件如`compiled.php`,`routes.php`,`config.php`以及`service.json` ### 新增BroadcastServiceProvider 在配置文件`config/app.php`中,添加`Illuminate\Broadcasting\BroadcastServiceProvider`到`providers`数组。 ### 认证 如果你在使用Laravel自带的`AuthenticatesAndRegistersUsers`的`AuthController`,则需要对新用户的验证和创建做一些代码改动: 首先,你不再需要传递`Guard`和`Register`实例到构造函数,你可以从控制器的构造器中完全移除这些以依赖。 然后,Laravel 5.0中使用的`App\Services\Registrar`不再被需要,你可以直接简单拷贝粘贴其中的`validator`方法和`create`方法到`AuthController`中,这两个方法中的代码不需要做任何改动。不要忘记确认`Validator`和`User`在`AuthController`中是否已经被导入。 `PasswordController`不再需要在构造函数中声明任何依赖,可以移除5.0中要求的两个依赖。 ### 验证 如果你重写了`Controller`类中的`formatValidationErrors`方法,需要将类型提示由`Illuminate\Validation\Validator`改为`Illuminate\Contracts\Validation\Validator`。 ### Eloquent **create方法** Eloquent的`create`方法现在可以不传入任何参数进行调用,如果你在模型中要重写`create`方法,将`$attributes`参数的默认值改为数组: ~~~ public static function create(array $attributes = []){ // Your custom implementation } ~~~ **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(); ~~~ > 注意:Query Builder的lists返回的仍然是数组。 **日期格式化** 以前,模型中的Eloquent日期字段存储格式可以通过重写`getDateFormat`方法来修改,现在依然可以这么做;但是为了更加方便可以在模型中简单通过指定`$dateFormat`属性来替代重写方法。 在序列化模型到数组或JSON时日期格式也被应用到,当从Laravel 5.0迁移到5.1时,这将会改变JSON序列化的日期字段的格式。想要在序列化模型中设置指定的日期格式,你可以在模型中重写`serializeDate(DateTime $date)`方法,这样就可以在不改变字段存储格式的情况下对格式化序列化的Eloquent日期字段有着更加细粒度的控制。 ### Collection类 **sortBy方法** sortBy方法现在返回一个新的collection实例而不是改变已有的collection: ~~~ $collection = $collection->sortBy('name'); ~~~ **groupBy方法** `groupBy`方法现在为每个父级Collection中的item返回Collection实例,如果你想要将这些items转化为数组,可以通过`map`方法实现: ~~~ $collection->groupBy('type')->map(function($item){ return $item->all(); }); ~~~ **lists方法** lists方法现在返回一个Collection实例而不是数组,如果你想要将Collection转化数组,使用`all`方法: ~~~ $collection->lists('id')->all(); ~~~ ### 命令&处理器 `app/Commands`目录现在被重命名为`app/Jobs`,但是并不需要将你的命令移动到新位置,你可以继续使用`make:command`和`handler:command` Artisan 命令生成自己的类。 同样的,`app/Handlers`目录被合并到`app/Listeners`目录下,你也不必将已经存在的命令和事件处理器进行移动和重命名,你可以继续使用`handler:event`命令生成事件处理器。 通过提供对Laravel 5.0目录结构的向后兼容,你可以无缝升级应用到Laravel 5.1然后慢慢升级你的事件和命令到新的位置——在一个对你或你的团队合适的时间。 ### Blade `createMatcher`,`createOpenMatcher`和`createPlainMatcher`方法已经从Blade编译器中移除,可以使用新的`directive`方法来为5.1版的Blade创建自定义的指令。查阅扩展[Blade文档](http://laravelacademy.org/post/79.html#extend-blade)了解详情。 ### 测试 在tests/TestCase.php文件中新增protected属性`$baseUrl`: ~~~ protected $baseUrl = 'http://localhost'; ~~~ ### 翻译文件 用于为vendor包发布语言文件的默认目录做了移动,所有vendor包语言文件从`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 Web Services SDK 如果你正在使用AWS SQS队列驱动或者AWS SES电子邮件驱动,需要升级AWS PHP SDK到3.0版本。 如果你正在使用Amazon S3文件系统驱动,需要通过Composer升级相应的文件系统包: * Amazon S3: `league/flysystem-aws-s3-v3 ~1.0` ### 废弃 以下Laravel特性已经被废弃并且会在2015年12月份的Laravel 5.2中被完全移除: * [中间件](http://laravelacademy.org/post/57.html)中的路由过滤器 * `Illuminate\Contracts\Routing\Middleware`,中间件中不再需要任何contract,`Illuminate\Contracts\Routing\TerminableMiddleware`被废弃,在中间件中定义一个terminate方法替代实现该接口。 * `Illuminate\Contracts\Queue\ShouldBeQueued` 被废弃,使用 `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和query builder的 `pluck` 方法被废弃并重命名为`value`. * Collection的 `fetch` 方法被废弃,使用 `pluck` 方法. * `array_fetch` 帮助函数被废弃, 使用`array_pluck`