| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- <?php
- namespace PhpLife\Frame;
- class Dispatcher
- {
- const CONFIG_PREFIX = '\\PhpLife\\Config';
- const CONTROLLER_ERROR = 'Error';
- const CONTROLLER_DEFAULT = 'Index';
- const METHOD_DEFAULT = 'main';
- /**
- * 使用方法
- * @param $customPrefix
- * @param string $pathInfo
- */
- public static function run($customPrefix, $pathInfo = '')
- {
- // 获取前缀
- $prefix = '\PhpLife\\App\\' . self::convertToClassName($customPrefix) . "\\Controller";
- if (!$pathInfo) {
- $pathInfo = self::getPathInfo();
- }
- $pathInfo = self::convertToClassName($pathInfo);
- $pathInfo = explode('\\', $pathInfo);
- if(count($pathInfo) > 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;
- }
- }
|