ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
[TOC] ## 问题 * `php artisan migrate` 报错问题 ``` SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes (SQL: alter table `users` add unique `users_email_unique`(`email`)) ``` > * 跟数据库编码问题有关, `laravel 5.4`开始采用的是 `utf8mb4`编码 > *  解决办法: 修改`/app/providers/AppServiceProvider.php`文件 > * `use Illuminate\Support\Facades\Schema;` > * `Schema::defaultStringLength(191);` 添加至:`boot` 方法 ## 服务容器问题 ### 1.服务是什么? >* 服务是提供了一些功能的类,比如发送邮件,写日志. ### 2.Laravel服务提供者是什么? >* 服务提供者中指明了这个提供者可以提供哪些服务(注册服务),以及服务注册后默认调用一些方法(`boot`). ### 3.能否不用服务提供者,直接调用服务? >* 可以,依靠Laravel的依赖注入,你可以方便的调用任何一个服务,而不用服务提供者。 ### 4.既然3成立,那么服务提供者有什么存在的必要? >* 1. 利用服务提供者的`boot`方法,可以做一些全局性的设置,如在`boot`中对`view`的`composer` >* 2. 服务提供者利用`bind`或`singleton`可以实现一个接口到实现类绑定,调用该服务对应的接口,会返回了一个具体的实现类。 >* 3. 这不是更复杂了么? 是的,是有点复杂,但好处是松耦合,更加灵活,调整服务也变的更加简单。 ### 5.服务容器是什么? > * 服务容器是一个用于管理类依赖和执行依赖注入的强大工具。 > * 简而言之就是,你将功能类(服务)作为参数传递到一个容器类中,以后直接调用容器类就可以。 > * 服务提供者的绑定就是向Laravel核心容器类,传递了一个服务类来做参数,核心容器类内部实现了绑定该服务作为容器类的一个属性。 ### 6.服务提供者在应用启动时,就会注册相应的服务,这会不会显得没有必要?因为有些情况下,不是应用开始就需要这个服务的. > * 是的,所以你可以在服务提供者中延迟加载,只有在你需要的时候才加载这个服务。 > * 设置服务提供者的`defer`属性和`provides`方法。 ### 7.服务提供者功能之一是实现了一个接口到实现类的绑定,能否根据具体情况,比如A控制器中调用服务接口实现接口的A实现类,B控制器中调用接口的B实现类? > * 可以,在服务提供者中绑定的时候实现依据上下文环境绑定。 > ``` > $this->app->when('App\\Handlers\\Commands\\CreateOrderHandler') > ->needs('App\\Contracts\\EventPusher') > ->give('App\\Services\\PubNubEventPusher'); > ``` ### 8.有没有一个服务提供者聚合多个服务的结果,对外使用一个统一的名称来访问? > * 可以,使用服务提供者的标签 ### 9.能从服务容器中解析出一个对象吗? > * 可以. > * 1. 使用`$this->app->make('xxx')`或`$this->app\['xxx'\]`,在控制器中使用帮助函数`app()->make('XXX')` > * 2. 可以简单的通过在类的构造函数中对依赖进行类型提示来从容器中解析对象,包括控制器、事件监听器、队列任务、中间件等都是通过这种方式 > ``` > public function __construct(UserRepository $users) >{ > $this->users = $users; >} > ``` ### 10.能否在从容器中解析对象的时候触发一个事件? > * 可以,在服务提供者中使用`$this->app->resolving` ### 11.门面和契约是什么? > * 1. Laravel 的契约是指框架提供的一系列定义核心服务的接口, > > * 比如, `Illuminate\\Contracts\\Queue\\Queue` 契约定义了队列任务需要的方法, > > * `Illuminate\\Contracts\\Mail\\Mailer` 契约定义了发送邮件所需要的方法。每一个契约都有框架提供的相应实现。 > > * 比如,Laravel 提供了多个驱动的队列实现,邮件实现则由 SwiftMailer驱动。所有的 Laravel 契约都有其 GitHub 库,这为所有有效的契约提供了快速入门指南,同时也可以作为独立、解耦的包被包开发者使用。 > * 2. Laravel 的门面为 Laravel 服务的使用提供了一个简便的方式——不再需要从服务容器中类型提示和解析契约.如`Auth::user()`,`Auth::check()` `Cache::get()`等 ### 12.基本点 > * 服务提供者在项目根目录下的Providers > * 可以使用命令创建一个服务提供者 > * `php artisan make:provider TestProvider ` > * 每个服务提供者需要注册在在`config/app.php`的`providers`数组中