[Laravel] 17 - Server: Container, Provider and Eventing

前言


一、底层篇

 

二、资源

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

Ref: view composer in laravel

让一个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,

    ],
View Code

 

三、填充 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); //......各种实现 } }

 

 

posted @ 2018-07-16 08:29  郝壹贰叁  阅读(259)  评论(0)    收藏  举报