1){ $method = array_pop($pathInfo); }else{ $method = self::METHOD_DEFAULT; } $controller = $prefix . '\\' . implode('\\', $pathInfo); // 加入一次出错重试的机会 for ($i = 0; $i < 2; $i++) { try { // 判断是否是公开方法 $reflection = new \ReflectionMethod($controller, $method); if ($reflection->isPublic() == false) { throw new \Exception($controller . "::$method is not public"); } $controller = new $controller(); $controller->$method(); break; } catch (\Exception $ex) { Logger::emerg($ex, 'dispatcher.run'); $controller = $prefix . '\\' . self::CONTROLLER_ERROR; $method = self::METHOD_DEFAULT; } } } /** * 分发请求 * @param string $customPrefix * @param string $pathInfo */ public static function dispatch($customPrefix, $pathInfo = '') { // 获取前缀 $prefix = '\PhpLife\\App\\' . self::convertToClassName($customPrefix) . "\\Controller"; if (!$pathInfo) { $pathInfo = self::getPathInfo(); } $pathInfo = self::convertToClassName($pathInfo); try { $controller = $prefix . '\\' . $pathInfo; // 如果类不存在则使用默认的错误类 if (!class_exists($controller)) { Logger::error($controller, 'dispatcher.controller_not_exist'); $controller = $prefix . '\\' . self::CONTROLLER_ERROR; // 如果错误类也不存在,则抛出异常 if (!class_exists($controller)) { throw new \Exception($controller . ' not exist'); } } // 判断主方法 if (!method_exists($controller, 'run')) { throw new \Exception($controller . ' has no method called "run"'); } $controller = new $controller(); $controller->run(); } catch (\Exception $ex) { Logger::emerg($ex, 'dispatcher.dispatch'); } } /** * 获取pathInfo, 兼容Apache, Nginx * 如果使用Apache的话可以直接使用 $_SERVER['PATH_INFO']的 * @return string */ protected static function getPathInfo() { //去掉uri中的PHP_SELF 信息 $length = strlen($_SERVER['PHP_SELF']); if (substr($_SERVER['REQUEST_URI'], 0, $length) == $_SERVER['PHP_SELF']) { $request = substr($_SERVER['REQUEST_URI'], $length); } else { $request = $_SERVER['REQUEST_URI']; } // 去除 ?后面的部分 $request = parse_url($request); $request = $request['path']; $request = urldecode($request); $request = trim($request, '/_ '); // 去掉 '.' 后缀 if (strpos($request, '.') !== false) { $request = explode('.', $request); $request = array_shift($request); } if (empty($request)) { $request = self::CONTROLLER_DEFAULT; } return $request; } /** * 将字符串转成带命名空间的类名 * @param $string * @return string */ public static function convertToClassName($string) { $string = trim($string, '\\/_ '); $string = strtolower($string); $string = str_replace('/', '\\', $string); $string = str_replace(' ', '\\', ucwords(str_replace('\\', ' ', $string))); $string = str_replace(' ', '', ucwords(str_replace('_', ' ', $string))); return $string; } }