Laravel Event模块分析
事件模块是一个由四个静态数组构成的部件,存在于内存中,提供事件模拟。
<?php namespace Laravel;
class Event {
/**
* 所有注册的事件
*
* @var array
*/
public static $events = array();
/**
* 队列事件 等待flush
*
* @var array
*/
public static $queued = array();
/**
* 队列flush之后回调
*
* @var array
*/
public static $flushers = array();
/**
* 注册事件是否有回调
*
* @param string $event
* @return bool
*/
public static function listeners($event)
{
return isset(static::$events[$event]);
}
/**
* 注册事件回调
*
* <code>
* // "start" 事件
* Event::listen('start', function() {return 'Started!';});
*
* // 注册对象实例方法回调
* Event::listen('event', array($object, 'method'));
* </code>
*
* @param string $event
* @param mixed $callback
* @return void
*/
public static function listen($event, $callback)
{
static::$events[$event][] = $callback; # 数据格式 [$event] array $object,methodName
}
/**
* 给定事件重写所有回调
*
* @param string $event
* @param mixed $callback
* @return void
*/
public static function override($event, $callback)
{
static::clear($event);
static::listen($event, $callback);
}
/**
* 队列增加数据
*
* @param string $queue
* @param string $key
* @param mixed $data
* @return void
*/
public static function queue($queue, $key, $data = array())
{
static::$queued[$queue][$key] = $data;
}
/**
* 注册队列执行回调
*
* @param string $queue
* @param mixed $callback
* @return void
*/
public static function flusher($queue, $callback)
{
static::$flushers[$queue][] = $callback;
}
/**
* 清楚所给事件回调
*
* @param string $event
* @return void
*/
public static function clear($event)
{
unset(static::$events[$event]);
}
/**
* 触发事件 返回第一值
*
* <code>
* // Fire the "start" event
* $response = Event::first('start');
*
* // Fire the "start" event passing an array of parameters
* $response = Event::first('start', array('Laravel', 'Framework'));
* </code>
*
* @param string $event
* @param array $parameters
* @return mixed
*/
public static function first($event, $parameters = array())
{
return head(static::fire($event, $parameters)); # 执行所有回调 但只提取第一值
}
/**
* 触发事件返回第一个值
*
* 第一个值返回之后执行被挂起
*
* @param string $event
* @param array $parameters
* @return mixed
*/
public static function until($event, $parameters = array())
{
return static::fire($event, $parameters, true); # 未执行所有回调 只执行第一值
}
/**
* 刷新事件多列, 触发每个占位
*
* @param string $queue
* @return void
*/
public static function flush($queue)
{
foreach (static::$flushers[$queue] as $flusher)
{
if ( ! isset(static::$queued[$queue])) continue;
foreach (static::$queued[$queue] as $key => $payload)
{
array_unshift($payload, $key); # 调整参数
call_user_func_array($flusher, $payload); # 调用
}
}
}
/**
* 触发事件所有监听器
*
* <code>
* // "start" 事件
* $responses = Event::fire('start');
*
* // "start" 事件参数
* $responses = Event::fire('start', array('Laravel', 'Framework'));
*
* // 同一参数触发多个事件
* $responses = Event::fire(array('start', 'loading'), $parameters);
* </code>
*
* @param string|array $events
* @param array $parameters
* @param bool $halt
* @return array
*/
public static function fire($events, $parameters = array(), $halt = false)
{
$responses = array();
$parameters = (array) $parameters; # 参数是array
// 遍历触发 返回结果集
foreach ((array) $events as $event)
{
if (static::listeners($event))
{
foreach (static::$events[$event] as $callback) # 遍历监听器
{
$response = call_user_func_array($callback, $parameters); # 实例方法触发原因:call_user_func_array 换成反射就能提供更多方式 换成Ding更好
// 第一值返回挂起
if ($halt and ! is_null($response))
{
return $response;
}
// 结果集
$responses[] = $response;
}
}
}
return $halt ? null : $responses; # 挂起标记
}
}
只提供模拟,不支持数据化,不支持分布式。
不过够简单,简洁就是美丽。
就理解上来说,事件模块可以被其他所有模块调用,但是需要安排好唯一标识,防止覆写。

浙公网安备 33010602011771号