Hook类代码改进

1.改进get方法:防止数组索引未定义的异常;
2.改进listen方法:$once=true的时候有可能没有日志记录;返回最后一条执行结果;
3.改进import和add方法:_overlay配置由add方法处理;允许callable形式添加;
4.修改exec方法:日志记录由exec实现,减少两次判断。
This commit is contained in:
WeakSun
2016-09-11 17:24:21 +08:00
committed by GitHub
parent 93e0eb46d3
commit f4df441b11

View File

@@ -1,4 +1,5 @@
<?php <?php
// +---------------------------------------------------------------------- // +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ] // | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +---------------------------------------------------------------------- // +----------------------------------------------------------------------
@@ -29,11 +30,15 @@ class Hook
*/ */
public static function add($tag, $behavior, $first = false) public static function add($tag, $behavior, $first = false)
{ {
if (!isset(self::$tags[$tag])) { isset(self::$tags[$tag]) || self::$tags[$tag] = [];
self::$tags[$tag] = []; if (is_array($behavior) && !is_callable($behavior)) {
} if (!array_key_exists('_overlay', $behavior) || !$behavior['_overlay']) {
if (is_array($behavior)) { unset($behavior['_overlay']);
self::$tags[$tag] = array_merge(self::$tags[$tag], $behavior); self::$tags[$tag] = array_merge(self::$tags[$tag], $behavior);
} else {
unset($behavior['_overlay']);
self::$tags[$tag] = $behavior;
}
} elseif ($first) { } elseif ($first) {
array_unshift(self::$tags[$tag], $behavior); array_unshift(self::$tags[$tag], $behavior);
} else { } else {
@@ -46,28 +51,14 @@ class Hook
* @param array $tags 插件信息 * @param array $tags 插件信息
* @param boolean $recursive 是否递归合并 * @param boolean $recursive 是否递归合并
*/ */
public static function import($tags, $recursive = true) public static function import(array $tags, $recursive = true)
{ {
empty($tags) && $tags = []; if ($recursive) {
if (!$recursive) { foreach ($tags as $tag => $behavior) {
// 覆盖导入 self::add($tag, $behavior);
self::$tags = array_merge(self::$tags, $tags); }
} else { } else {
// 合并导入 self::$tags = $tags + self::$tags;
foreach ($tags as $tag => $val) {
if (!isset(self::$tags[$tag])) {
self::$tags[$tag] = [];
}
if (!empty($val['_overlay'])) {
// 可以针对某个标签指定覆盖模式
unset($val['_overlay']);
self::$tags[$tag] = $val;
} else {
// 合并模式
self::$tags[$tag] = array_merge(self::$tags[$tag], $val);
}
}
} }
} }
@@ -78,11 +69,10 @@ class Hook
*/ */
public static function get($tag = '') public static function get($tag = '')
{ {
if (empty($tag)) { if (empty($tag)) {//获取全部的插件信息
// 获取全部的插件信息
return self::$tags; return self::$tags;
} else { } else {
return self::$tags[$tag]; return array_key_exists($tag, self::$tags) ? self::$tags[$tag] : [];
} }
} }
@@ -97,36 +87,16 @@ class Hook
public static function listen($tag, &$params = null, $extra = null, $once = false) public static function listen($tag, &$params = null, $extra = null, $once = false)
{ {
$results = []; $results = [];
if (isset(self::$tags[$tag])) { $tags = static::get($tag);
foreach (self::$tags[$tag] as $name) { foreach ($tags as $key => $name) {
$results[$key] = self::exec($name, $tag, $params, $extra);
if (App::$debug) { if (false === $results[$key]) {// 如果返回false 则中断行为执行
Debug::remark('behavior_start', 'time'); break;
} } elseif (!is_null($results[$key]) && $once) {
$result = self::exec($name, $tag, $params, $extra);
if (!is_null($result) && $once) {
return $result;
}
if (App::$debug) {
Debug::remark('behavior_end', 'time');
if ($name instanceof \Closure) {
$name = 'Closure';
} elseif (is_object($name)) {
$name = get_class($name);
}
Log::record('[ BEHAVIOR ] Run ' . $name . ' @' . $tag . ' [ RunTime:' . Debug::getRangeTime('behavior_start', 'behavior_end') . 's ]', 'info');
}
if (false === $result) {
// 如果返回false 则中断行为执行
break; break;
} }
$results[] = $result;
} }
} return $once ? end($results) : $results;
return $once ? null : $results;
} }
/** /**
@@ -139,14 +109,22 @@ class Hook
*/ */
public static function exec($class, $tag = '', &$params = null, $extra = null) public static function exec($class, $tag = '', &$params = null, $extra = null)
{ {
if ($class instanceof \Closure) { App::$debug && Debug::remark('behavior_start', 'time');
if (is_callable($class)) {
$result = call_user_func_array($class, [ & $params, $extra]); $result = call_user_func_array($class, [ & $params, $extra]);
$class = 'Closure';
} elseif (is_object($class)) { } elseif (is_object($class)) {
$result = call_user_func_array([$class, $tag], [ & $params, $extra]); $result = call_user_func_array([$class, $tag], [ & $params, $extra]);
$class = get_class($class);
} else { } else {
$obj = new $class(); $obj = new $class();
$result = ($tag && is_callable([$obj, $tag])) ? $obj->$tag($params, $extra) : $obj->run($params, $extra); $result = ($tag && is_callable([$obj, $tag])) ? $obj->$tag($params, $extra) : $obj->run($params, $extra);
} }
if (App::$debug) {
Debug::remark('behavior_end', 'time');
Log::record('[ BEHAVIOR ] Run ' . $class . ' @' . $tag . ' [ RunTime:' . Debug::getRangeTime('behavior_start', 'behavior_end') . 's ]', 'info');
}
return $result; return $result;
} }
} }