事件存在很多方面,比如登录、购买商品、搜索、查看文章等等。 监听器监听到事件发生后,会执行一些操作。Laravel
使用观察者模式来实现这种监听机制。 现在我们通过一个用户登录来讲解一个事件,监听一个事件并触发一些操作的全过程。
Registering Events / Listeners
首先,在App/Providers/EventServiceProvider.php
中注册事件与监听器之间的映射关系。下面的三个映射关系中我们只用到了LoginEvent
和LoginSuccess
protected $listen = [
'App\Events\LoginEvent' => ['App\Listeners\LoginSuccess'],
'App\Events\LogoutEvent' => ['App\Listeners\LogoutSuccess'],
'App\Events\UserAccess' => ['App\Listeners\UserAccess']
];
然后,在根目录下执行artisan
$ php artisan event:generate
执行命令成功后,分别会在App/Events
和App\Listeners
下生成App/Events/LoginEvent
和App/Listeners/LoginSuccess
等php
文件
定义事件类
<?php
namespace App\Events;
use App\Events\Event;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class LoginEvent extends Event
{
use SerializesModels;
/**
* Create a new event instance.
*
* @return void
*/
function __construct()
{
}
/**
* Get the channels the event should be broadcast on.
*
* @return array
*/
public function broadcastOn()
{
return [];
}
}
在LoginEvent
事件中什么都没有改动,也不需要改动
定义监听器
现在在App/Listeners
中有了一个LoginSuccess.php
监听器,为了以后方面,我们在App/Listeners
中新建一个基础的监听类ListenerBase.php
<?php
namespace App\Listeners;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Services\Statut;
class ListenerBase
{
/**
* The statut intance
*
* @var App\Services\Statut
*/
protected $statut;
/**
* Create a listener event
*
* @param App\Service\Statut $statut
* @return void
*/
function __construct()
{
$this->statut = new Statut;
}
}
?>
ListenerBase.php
中实例化了一个Statut
类,这个Statut
类在App/Services文件夹下,下面我们会用到。
现在来到App/Listeners/LoginSuccess.php
<?php
namespace App\Listeners;
use App\Events\LoginEvent;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
class LoginSuccess extends ListenerBase
{
/**
* Create the event listener.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Handle the event.
*
* @param LoginEvent $event
* @return void
*/
public function handle(LoginEvent $event)
{
$this->statut->setLoginStatut($event);
}
}
LoginSuccess
继承了ListenerBase
, handle方法中$this->statut->setLoginStatut
获取了登录用户的状态
Statut.php
在App/Services
中新建php
文件Statut.php
,再此文件中,主要定义了获取当前登录用户的状态的几个方法,当触发事件后,会执行Statut.php
文件中的操作
<?php
namespace App\Services;
/**
*
*/
class Statut
{
function __construct()
{
# code...
}
/**
* Set the login user statut
*
* @var App\Event\LoginEvent
* @return void
*/
public function setLoginStatut($event){
session()->put('statut', auth()->user()->role->slug);//auth()->user()在用户登录完成后才会有值
}
/**
* Set visitor statut
*
* @return void
*/
public function setVisitorStatut(){
session()->put('statut', 'visitor');
}
/**
* Set the statut
*
* @return void
*/
public function setStatut(){
if(!session()->has('statut')){
session()->put('statut', auth()->check() ? auth()->user()->role->slug : 'visitor');
}
}
}
?>
好了,事件和监听器完成之后,就需要触发操作了,这里我们用中间件(Middleware
)
Defining Middleware
使用artisan
命令来创建中间件 App/Http/Middleware/App.php
$ php artisan make:middleware App
执行成功后,使用全局方法event
<?php
namespace App\Http\Middleware;
use Closure;
use App\Events\LoginEvent;
class App
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
event(new LoginEvent); //实例化App/Events/UserAccess,
return $next($request);
}
}
最后,再将App
中间件注册到kernel.php中
<?php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
*
* @var array
*/
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\App\Http\Middleware\App::class, //App中间件
];
完成上面的操作后,就可以获取用户的登录状态了。在Statut.php
中,我们把用户状态分为visitor
,admin
,user
,根据登录用户的不同状态来显示出不同的内容。例如,如果是admin
,则他可以进入后台并执行一些操作,如果是user
或者visitor
,那么他只能浏览一些页面
总结:
了解自己想要做什么,达到什么样的目的,操作的过程中,思路应清晰。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。