[Laravel] 17 - Server: Container, Provider and Eventing
前言
一、底层篇
- Laravel 5.x 启动过程分析
- Laravel 服务容器实例教程 —— 深入理解控制反转(IoC)和依赖注入(DI)
- Laravel 服务提供者实例教程 —— 创建 Service Provider 测试实例
- Laravel 门面实例教程 —— 创建自定义 Facades 类
二、资源
Ref: 解释清楚Laravel的Service Container, Service Provider,Contracts和Facade之间的关系
Ref: [Laravel]唠唠Service Container
本篇还在整理中 。。。
Service Provider
一、何谓 Service Provider
View Composers 与视图有关,用在一个service provider 的boot()函数里,
就是让一个view加载的时候,由于view composer的作用,去调用某个函数传个参啊啥的。
创建一个 provider.php

让一个view加载的时候,由于view composer的作用,去调用某个函数传个参数。
二、创建 service provider
php artisan make:provider ComposerServiceProvider
再把 ComposerServiceProvider -- 加到 --> config/app.php。
/* |-------------------------------------------------------------------------- | Autoloaded Service Providers |-------------------------------------------------------------------------- | | The service providers listed here will be automatically loaded on the | request to your application. Feel free to add your own services to | this array to grant expanded functionality to your applications. | */ 'providers' => [ /* * Laravel Framework Service Providers... */ Illuminate\Auth\AuthServiceProvider::class, Illuminate\Broadcasting\BroadcastServiceProvider::class, Illuminate\Bus\BusServiceProvider::class, Illuminate\Cache\CacheServiceProvider::class, Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class, Illuminate\Cookie\CookieServiceProvider::class, Illuminate\Database\DatabaseServiceProvider::class, Illuminate\Encryption\EncryptionServiceProvider::class, Illuminate\Filesystem\FilesystemServiceProvider::class, Illuminate\Foundation\Providers\FoundationServiceProvider::class, Illuminate\Hashing\HashServiceProvider::class, Illuminate\Mail\MailServiceProvider::class, Illuminate\Pagination\PaginationServiceProvider::class, Illuminate\Pipeline\PipelineServiceProvider::class, Illuminate\Queue\QueueServiceProvider::class, Illuminate\Redis\RedisServiceProvider::class, Illuminate\Auth\Passwords\PasswordResetServiceProvider::class, Illuminate\Session\SessionServiceProvider::class, Illuminate\Translation\TranslationServiceProvider::class, Illuminate\Validation\ValidationServiceProvider::class, Illuminate\View\ViewServiceProvider::class, /* * Application Service Providers... */ App\Providers\AppServiceProvider::class, App\Providers\AuthServiceProvider::class, App\Providers\EventServiceProvider::class, App\Providers\RouteServiceProvider::class, ],
三、填充 boot
public function boot() { view()->composer( 'app', # 一旦加载 app.blade.php 'App\Http\ViewComposers\MovieComposer' # 就默认执行里面的 composer函数; 如果自定义执行,可以这么写:MovieComposer@foobar ); }
不妨写成如下,'匿名函数' 的形式。
public function boot() { view()->composer(
'layouts.sidebar',
function($view) { $view->with('archives', \App\Post::archives()); }
); }
Service Container
帮助我们管理和进行依赖注入的。
既然是一个容器,无非就是两个事,往里放东西和往外取东西,对应到Service Container就是绑定(Binding)和解析(Resolving)。
# 获取容器 $this->app app()
Continue...
Eventing
一、简介
- Event and Listeners
Laravel 事件提供了简单的观察者模式实现,允许你订阅和监听应用中的事件。
-
- 事件类通常存放在
app/Events目录, - 监听器存放在
app/Listeners。
- 事件类通常存放在
二、注册事件/监听器
- 自动注册
让我们添加一个 OrderShipped 事件:
/** * 应用的事件-监听器映射. * * @var array * @translator laravelacademy.org */ protected $listen = [ 'App\Events\OrderShipped' => [ 'App\Listeners\SendShipmentNotification', ], ];
Laravel 自带的 EventServiceProvider 为事件监听器注册提供了方便之所。
[1] 添加监听器和事件到 EventServiceProvider。

[2] 将会生成以上文件中的所有 "事件和监听器"。
php artisan event:generate
- 手动注册
此外,你还可以在 EventServiceProvider 的 boot 方法中手动注册基于闭包的事件:
/** * 注册应用的其它事件. * * @return void */ public function boot() { parent::boot(); Event::listen('event.name', function ($foo, $bar) { // }); }
使用通配符*来注册监听器,这样就可以通过同一个监听器捕获多个事件。
通配符监听器接收整个事件数据数组作为参数:'event.*'
三、定义 '事件'
事件类 是一个处理与事件相关的简单数据容器。
例如,假设我们生成的 OrderShipped 事件接收一个 Eloquent ORM对象:
<?php
namespace App\Events;
use App\Order;
use Illuminate\Queue\SerializesModels;
class OrderShipped
{
use SerializesModels;
public $order; // 只是一个存放被购买的 Order 对象的容器
public function __construct(Order $order)
{
$this->order = $order;
}
}
序列化: 如果事件对象被序列化的话,事件使用的 SerializesModels trait 将会使用 PHP 的 serialize 函数序列化所有 Eloquent 模型。
四、定义 '监听器'
<?php namespace App\Listeners; use App\Events\OrderShipped;
use Illuminate\Contracts\Queue\ShouldQueue; class SendShipmentNotification implements ShouldQueue { public function __construct() { // 创建事件监听器 } public function handle(OrderShipped $event) { // 处理事件 - 使用 $event->order 发访问订单... } }
队列化监听器:
当这个监听器被调用的时候,将会使用 Laravel 的队列系统通过事件分发器自动推送到队列。如果通过队列执行监听器的时候没有抛出任何异常,队列任务会在执行完成后被自动删除。
Next, 事件监听器队列
一个简单案例
Ref: 最简单易懂的laravel事件,这个功能非常的有用
"先说一下在什么场景会使用这个事件功能,..." 【这才是良心博文】
- 原始思路
希望在注册过程中顺便添加一些功能。
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; class UserController extends Controller { public function register(Request $request) { // 获取参数 // 验证参数 // 写入数据库 // 发送广告邮件 // 发送短信
/* 插入点 */
// return 注册信息 } }
- Laravel的事件功能
[1] laravel的事件功能实际上更倾向是一种管理手段,并不是没了它我们就做不到了,只是它能让我们做得更加好,更加优雅。
[插入点]
//event方法是laravel自带方法, $uid是外部参数 event(new Register($uid));
[2] 给它添加关系,告诉系统,有人用 event() 调用该事件之后,要被谁监听得到。
这里是注册事件的入口,相当于一个总目录,这样就可以跟注册代码解耦了。
[\app\Providers\EventServiceProvider.php]
<?php namespace App\Providers; use Laravel\Lumen\Providers\EventServiceProvider as ServiceProvider; class EventServiceProvider extends ServiceProvider { protected $listen = [ 'App\Events\Register' => [
// 发送广告邮件 'App\Listeners\SendAdMail', --> 监听Register // 发送短信 'App\Listeners\SendSms', --> 监听Register // 发送帮助信息 'App\Listeners\SendHelpInformation', --> 监听Register ], ]; }
- 创建 Register 这个类
现在注册完之后
(1) 会触发这个App\Events\Register类,
(2) 然后这个类会被 App\Listeners\SendAdMail, App\Listeners\SendSms, App\Listeners\SendHelpInformation 监听得到。
<?php namespace App\Events; class Register { public $uid; public function __construct($uid) { $this->uid = $uid; } }
- 创建 事件监听类 Listener
接下来,去app\Listeners目录,创建各种要做的 '事件监听类'。
多人开发也是单独写自己的Listeners就可以了。
use App\Events\Register; use App\Models\User; use Illuminate\Contracts\Queue\ShouldQueue;
/**
* implements ShouldQueue
* 这里是队列执行,
* 去掉的话就是同步执行;
*
*/ class SendHelpInformation implements ShouldQueue { public function __construct() { // } public function handle(Register $event) // <---- 具体实现 { $uid = $event->uid; $user = User::find($uid); //......各种实现 } }

浙公网安备 33010602011771号