• 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; # 挂起标记
    	}
    
    }
    

    只提供模拟,不支持数据化,不支持分布式。
    不过够简单,简洁就是美丽。

    就理解上来说,事件模块可以被其他所有模块调用,但是需要安排好唯一标识,防止覆写。

      

  • 相关阅读:
    xp_cmdshell
    常用SQL语句
    SQL Server Select的递归查询-交叉表
    Sql Server 2005 行转列的实现(横排)
    sql导入导出
    使用正则表达式验证手机号、车牌号
    页面功能:设为首页和加入收藏
    两个文本框同步输入
    最常用的200个JS代码
    .NET 获取时间
  • 原文地址:https://www.cnblogs.com/snakevash/p/2993761.html
Copyright © 2020-2023  润新知