/**
* 获取invoker信息
*
* @param Invoker $invoker
* @param $method http方法
* @param $uri http url
* @return array
*/
public function getInvokerInfo($method, $uri, $invoker)
{
$res = array();
$res['impl'] = $invoker->getMethodName();
$ann = new AnnotationReader();
$refl = new \ReflectionClass($invoker->getClassName());
$mrefl = $refl->getMethod($invoker->getMethodName());
$anns = $ann->getMethodAnnotations($mrefl, true);
// 过滤无效的参数
if (isset($anns['param'])) {
$anns['param'] = array_values(array_filter($anns['param'], function ($i) {
return isset($i['value']);
}));
}
if (isset($anns['return'])) {
$anns['return'] = array_values(array_filter($anns['return'], function ($i) {
return isset($i['value']);
}));
}
if (isset($anns['throws'])) {
$anns['throws'] = array_values(array_filter($anns['throws'], function ($i) {
return isset($i['value']);
}));
}
$res['doc'] = $this->getDocText($mrefl->getDocComment());
//找到匹配的@route注释
foreach ($anns['route'] as $route_doc) {
//TODO: 同时精确匹配和通配符匹配时, 怎么处理
if (isset($route_doc['value'])) {
list($m, $u) = $route_doc['value'];
$full_url = $invoker->getContainer()->path . '/' . $u;
$full_url = HttpRouterEntries::stringToPath($full_url);
if ($full_url == HttpRouterEntries::stringToPath($uri) && $m === $method) {
$text = $this->getDocText($route_doc['desc']);
if (!empty($text)) {
$res['doc'] .= "\r\n";
$res['doc'] .= $text;
}
break;
}
}
}
$anns['route'];
$res['root'] = '/';
$res['path'] = $invoker->getContainer()->path;
// 获取参数信息
$res['params'] = array();
foreach ($invoker->getParams()->getParams() as $param) {
list($is_const, $value, $info, $id) = $param;
list($name, $is_ref, $is_optional, $default) = $info;
if (!$is_const) {
$res['params'][$name] = array('value' => $value, 'is_ref' => $is_ref, 'is_optional' => $is_optional, 'default' => $default, 'doc' => $this->getDocText($anns['param'][$id]['desc']));
}
}
// 依赖只是特殊的参数
$defaults = $refl->getDefaultProperties();
foreach ($refl->getProperties() as $property) {
foreach ($ann->getPropertyAnnotations($property, true) as $type => $value) {
if ($type !== 'inject') {
continue;
}
$name = $property->getName();
$value = $value[0];
if (is_array($value['value'])) {
$src = $value['value']['src'];
if (isset($value['value']['optional']) && $value['value']['optional']) {
$is_optional = true;
}
if (isset($value['value']['default'])) {
$default = $value['value']['default'];
}
} else {
$src = $value['value'];
}
if (substr($src, 0, 1) !== '$') {
continue;
}
if (array_key_exists($name, $defaults)) {
$is_optional = true;
$default = $defaults[$name];
}
$res['params'][$name] = array('value' => $src, 'is_ref' => false, 'is_optional' => $is_optional, 'default' => $default, 'doc' => $this->getDocText($value['desc']));
}
}
// 获取返回值信息
$res['returns'] = array();
foreach ($invoker->getReturns()->getParams() as $fun_name => $calls) {
foreach ($calls as $id => $call) {
$args = array();
foreach ($call as $num => $arg) {
list($is_const, $value, $pos, $info) = $arg;
list($name, $is_ref, $is_optional, $default) = $info;
$args[$num] = array('value' => $value, 'name' => $name, 'is_const' => $is_const);
}
$res['returns'][] = array('name' => $fun_name, 'args' => $args, 'doc' => $id === -1 ? null : $this->getDocText($anns['return'][$id]['desc']));
}
}
// 获取异常信息
$res['throws'] = array();
foreach ($invoker->getThrows()->getParams() as $exce_name => $throws) {
// $res['throws'][$exce_name] = array();
foreach ($throws as $fun_name => $calls) {
foreach ($calls as $id => $call) {
$args = array();
if ($call !== null) {
foreach ($call as $num => $arg) {
$args[$num] = array('value' => $arg, 'name' => null, 'is_const' => true);
}
}
$res['throws'][$exce_name][] = array('name' => $fun_name, 'args' => $args, 'doc' => $this->getDocText($anns['throws'][$id]['desc']));
}
}
}
return $res;
}