/** * Invokes a method. * * @param mixed $func Class method * @param array $params Class method parameters * @return mixed Function results */ public static function invokeMethod($func, array &$params = array()) { list($class, $method) = $func; $cname = last(explode("\\", $class)); $GLOBALS['c'] = strtolower(rremove($cname, 'Controller')); $GLOBALS['a'] = $GLOBALS['__METHOD__'] = $method; $instance = new $class(); $key = cmkey($class, $method); if (isset($GLOBALS['meta'][$key])) { $GLOBALS['meta_key'] = $key; // 获取方法所对应的Meta信息 $meta = $GLOBALS['meta'][$key]; $route_type = $meta['route'][0]['uri']; $route_type = substr($route_type, 0, strpos($route_type, ' ')); if ($meta['route'][0]['params'] && is_array($meta['route'][0]['params'])) { } if ($meta['route'][0]['params'] && is_array($meta['route'][0]['params'])) { $route_parmas = array_slice($meta['route'][0]['params'], 0, count($params)); } else { $route_parmas = false; } // 不管自动检查是否打开,先处理field_check if (isset($meta['Params']) && is_array($meta['Params'])) { foreach ($meta['Params'] as $item) { if (isset($item['name'])) { $item['name'] = ltrim($item['name'], '$'); } if (isset($item['cnname'])) { $item['cnname'] = trim($item['cnname'], '"'); } $to_check[$item['name']] = $item; } } // 开始根据to_check数组,对输入项进行检查 if (isset($to_check) && is_array($to_check)) { foreach ($to_check as $key => $item) { if (isset($item['filters']) && is_array($item['filters'])) { foreach ($item['filters'] as $check_function) { $tinfo = explode('_', $check_function); $type = reset($tinfo); $type = strtolower(trim($type)); if ($type == 'check') { // 当函数调用为false时直接输出错误信息 if (function_exists($check_function)) { //echo $item['name'] . '~' . print_r( $meta['route'][0]['params'] , 1 ); // 如果是路由器自带变量 if ($route_parmas && isset($meta['route'][0]['params']) && in_array($item['name'], $route_parmas)) { $vv = $params[array_search($item['name'], $route_parmas)]; } else { $vv = v($item['name']); } // 按名字从REQUEST中获取 $ret = call_user_func($check_function, $vv); if (!$ret) { // 抛出异常 if (is_devmode()) { throw new InputException($item['cnname'] . "(" . $item['name'] . ")未提供或格式不正确 via " . $check_function . " return {$ret}"); } else { throw new InputException($item['cnname'] . "(" . $item['name'] . ")未提供或格式不正确"); } } } } else { // filter // 修改request数值 if (function_exists($check_function)) { if ($route_parmas && isset($meta['route'][0]['params']) && in_array($item['name'], $route_parmas)) { $params[array_search($item['name'], $route_parmas)] = call_user_func($check_function, $params[array_search($item['name'], $route_parmas)]); } elseif (isset($_REQUEST[$item['name']])) { $php_uri_type = '_' . strtoupper($route_type); switch ($php_uri_type) { case '_GET': $_GET[$item['name']] = call_user_func($check_function, $_REQUEST[$item['name']]); break; case '_POST': $_POST[$item['name']] = call_user_func($check_function, $_REQUEST[$item['name']]); break; case '_PUT': $_PUT[$item['name']] = call_user_func($check_function, $_REQUEST[$item['name']]); break; case '_DELETE': $_DELETE[$item['name']] = call_user_func($check_function, $_REQUEST[$item['name']]); break; } } } } } } // 如果写入了参数绑定 // 注意这个地方是依赖于参数顺序的 // 如果在路由中 if (!($route_parmas && in_array($item['name'], $route_parmas))) { if (isset($meta['binding'][$item['name']])) { // 变量顺序按绑定顺序排序 $index = array_key_index($item['name'], $meta['binding']); $request_params[$index] = isset($meta['binding'][$item['name']]['default']) && !isset($_REQUEST[$item['name']]) ? $meta['binding'][$item['name']]['default'] : v($item['name']); } } // slog($request_params); } } //slog($meta['binding']); } // 强制request变量按function参数顺序进行绑定 if (isset($request_params) && is_array($request_params)) { ksort($request_params); $params = array_merge($params, $request_params); } return call_user_func_array(array($instance, $method), $params); }
/** * Gets all anotations with pattern @SomeAnnotation() from a determinated method of a given class * * @param string $className class name * @param string $methodName method name to get annotations * @return array self::$annotationCache all annotated elements of a method given */ public static function getMethodAnnotations($className, $methodName) { // 修改原有的注释 // 根据meta将注释重新展开为apidoc格式 // 如果未命中缓存 if (!isset(self::$annotationCache[$className . '::' . $methodName])) { try { $method = new \ReflectionMethod($className, $methodName); $doccoment = $method->getDocComment(); $doctext = substr($doccoment, 3, -2); $reg = '/@ApiLazyRoute\\(.+\\)/'; if (preg_match($reg, $doctext, $out)) { $old = $out[0]; //echo "\r\n\r\n ========== \r\n " . $old; //echo "\r\n\r\n ========== \r\n " ; //eval( '$auto_params = array( ' . $out[1] . ');' ); //print_r( $auto_params ); $key = cmkey($className, $methodName); if (isset($GLOBALS['meta']) && isset($GLOBALS['meta'][$key])) { $meta = $GLOBALS['meta'][$key]; $routeinfo = $meta['LazyRoute'][0]; //print_r( $routeinfo ); $replace = "@ApiMethod" . $routeinfo['ApiMethod'] . "\r\n * " . "@ApiRoute" . $routeinfo['ApiRoute']; //echo $replace; $doctext = str_replace($old, $replace, $doctext); $doccoment = "/**\r\n" . $doctext . "*" . "/"; } } /* // 检查是否有 apiRequiredParams $reg = '/@ApiRequiredParams\((.+?)\)/is'; if( preg_match( $reg , $doctext , $out ) ) { eval( '$require_params = array( ' . $out[1] . ');' ); } else $require_params = array(); //print_r( $require_params ); // 检查是否有 apiAutoParams // @apiAutoParams('id','name','email') $reg = '/@ApiAutoParams\((.+?)\)/is'; if( preg_match( $reg , $doctext , $out ) ) { $old = $out[0]; eval( '$auto_params = array( ' . $out[1] . ');' ); //print_r( $auto_params ); $key = cmkey( $className, $methodName ); if( isset( $GLOBALS['meta'] ) && isset( $GLOBALS['meta'][$key] ) ) { $meta = $GLOBALS['meta'][$key]; $fields = $meta['table'][0]['fields']; foreach( $auto_params as $aparam ) { if( isset( $fields[$aparam] ) ) { $f = $fields[$aparam]; if( in_array( $f['name'] , $require_params ) ) $null = 'false'; else $null = 'true' ; $to_array[] = '@ApiParams(name="'. $f['name'] .'", type="' . $f['type'] . '", nullable='. $null .', description="' . $f['comment'] . '")'; } } if( isset( $to_array ) ) { $replace = join( "\r\n * " , $to_array ); $doctext = str_replace( $old , $replace, $doctext); $doccoment = "/**\r\n" . $doctext . "*"."/"; } } } */ //echo $doccoment; $annotations = self::parseAnnotations($doccoment); } catch (\ReflectionException $e) { $annotations = array(); } self::$annotationCache[$className . '::' . $methodName] = $annotations; } return self::$annotationCache[$className . '::' . $methodName]; }
function build_route_file($return = false) { $meta = array(); if ($cfiles = glob(AROOT . 'controller' . DS . '*Controller.php')) { foreach ($cfiles as $cfile) { require_once $cfile; } } if ($classes = get_declared_classes()) { $ret = array(); foreach ($classes as $class) { if (end_with($class, 'Controller')) { // 开始遍历 $ref = new \ReflectionClass($class); if ($methods = $ref->getMethods()) { foreach ($methods as $method) { $item = array(); if ($item['meta'] = format_meta(parse_comment($method->getDocComment()))) { $item['class'] = $class; $item['method'] = $method->name; $item['meta']['binding'] = get_param_info($method->getParameters()); if (isset($item['meta']['LazyRoute'][0]['route'])) { $item['meta']['route'][] = array('uri' => $item['meta']['LazyRoute'][0]['route'], 'params' => get_route_params($item['meta']['LazyRoute'][0]['route'])); } $ret[] = $item; } } } } } if (count($ret) > 0) { foreach ($ret as $method_info) { // 只处理标记了路由的方法 if (isset($method_info['meta']['route'])) { //print_r( $method_info['meta']['route'] ); $key = cmkey($method_info); //echo "{$method_info['class']} , {$method_info['method']} = $key (build) \r\n"; $meta[$key] = $method_info['meta']; // 生成路由部分代码 foreach ($method_info['meta']['route'] as $route) { $source[] = '$app->' . "route('" . t($route['uri']) . "',array( '" . $method_info['class'] . "','" . $method_info['method'] . "'));"; } } } } } $GLOBALS['meta'] = $meta; if (isset($source) && is_array($source) && count($source) > 0) { $source_code = build_source_code($source, $meta); if ($return) { return $source_code; } else { save_route_file($source_code); } } }
/** * Invokes a method. * * @param mixed $func Class method * @param array $params Class method parameters * @return mixed Function results */ public static function invokeMethod($func, array &$params = array()) { list($class, $method) = $func; $instance = new $class(); $key = cmkey($class, $method); if (isset($GLOBALS['meta'][$key])) { $GLOBALS['meta_key'] = $key; // 获取方法所对应的Meta信息 $meta = $GLOBALS['meta'][$key]; if ($meta['route'][0]['params'] && is_array($meta['route'][0]['params'])) { $route_parmas = array_slice($meta['route'][0]['params'], 0, count($params)); } else { $route_parmas = false; } // 不管自动检查是否打开,先处理field_check // new verison changed filed_check to params if (isset($meta['Params']) && is_array($meta['Params'])) { foreach ($meta['Params'] as $item) { if (isset($item['name'])) { $item['name'] = ltrim($item['name'], '$'); } if (isset($item['cnname'])) { $item['cnname'] = trim($item['cnname'], '"'); } $to_check[$item['name']] = $item; } } // 开始根据to_check数组,对输入项进行检查 if (isset($to_check) && is_array($to_check)) { foreach ($to_check as $item) { if (isset($item['filters']) && is_array($item['filters'])) { foreach ($item['filters'] as $check_function) { $tinfo = explode('_', $check_function); $type = reset($tinfo); $type = strtolower(trim($type)); if ($type == 'check') { // 当函数调用为false时直接输出错误信息 if (function_exists($check_function)) { //echo $item['name'] . '~' . print_r( $meta['route'][0]['params'] , 1 ); // 如果是路由器自带变量 if ($route_parmas && isset($meta['route'][0]['params']) && in_array($item['name'], $route_parmas)) { $vv = $params[array_search($item['name'], $route_parmas)]; } else { $vv = v($item['name']); } // 按名字从REQUEST中获取 //echo $item['name'] .'s vv=' . $vv; if (!call_user_func($check_function, $vv)) { // 抛出异常 throw new InputException($item['cnname'] . "(" . $item['name'] . ")未提供或格式不正确 via " . $check_function); } } } else { // filter // 修改request数值 if (function_exists($check_function)) { if ($route_parmas && isset($meta['route'][0]['params']) && in_array($item['name'], $route_parmas)) { $params[array_search($item['name'], $route_parmas)] = call_user_func($check_function, $params[array_search($item['name'], $route_parmas)]); } elseif (isset($_REQUEST[$item['name']])) { $_REQUEST[$item['name']] = call_user_func($check_function, $_REQUEST[$item['name']]); //echo 'REQUEST[' . $item['name'] . ']='.$_REQUEST[$item['name']] .'\ED '; } } } } } // 如果写入了参数绑定 // 注意这个地方是依赖于参数顺序的 // 如果在路由中 if (!($route_parmas && in_array($item['name'], $route_parmas))) { if (isset($meta['binding'][$item['name']])) { // 变量顺序按绑定顺序排序 $index = array_key_index($item['name'], $meta['binding']); $request_params[$index] = v($item['name']); } } } } } // 强制request变量按function参数顺序进行绑定 if (isset($request_params) && is_array($request_params)) { ksort($request_params); $params = array_merge($params, $request_params); } return call_user_func_array(array($instance, $method), $params); }