// +---------------------------------------------------------------------- declare (strict_types = 1); namespace think\route\dispatch; use think\App; use think\exception\ClassNotFoundException; use think\exception\HttpException; use think\helper\Str; use think\route\Dispatch; /** * Controller Dispatcher */ class Controller extends Dispatch { /** * 控制器名 * @var string */ protected $controller; /** * 操作名 * @var string */ protected $actionName; public function init(App $app) { parent::init($app); $path = $this->dispatch; if (is_string($path)) { $path = explode('/', $path); } $action = !empty($path) ? array_pop($path) : $this->rule->config('default_action'); $controller = !empty($path) ? array_pop($path) : $this->rule->config('default_controller'); $layer = !empty($path) ? implode('/', $path) : ''; if ($layer && !empty($this->option['auto_middleware'])) { // 自动为顶层layer注册中间件 $alias = $app->config->get('middleware.alias', []); if (isset($alias[$layer])) { $this->app->middleware->add($layer, 'route'); } } // 获取控制器名和分层(目录)名 if (str_contains($controller, '.')) { $pos = strrpos($controller, '.'); $layer = ($layer ? $layer . '.' : '') . substr($controller, 0, $pos); $controller = Str::studly(substr($controller, $pos + 1)); } else { $controller = Str::studly($controller); } $this->actionName = strip_tags($action); $this->controller = strip_tags(($layer ? $layer . '.' : '') . $controller); // 设置当前请求的控制器、操作 $this->request ->setLayer(strip_tags($layer)) ->setController($this->controller) ->setAction($this->actionName); } public function exec() { try { // 实例化控制器 $instance = $this->controller($this->controller); } catch (ClassNotFoundException $e) { throw new HttpException(404, 'controller not exists:' . $e->getClass()); } return $this->responseWithMiddlewarePipeline($instance, $this->actionName); } /** * 实例化访问控制器 * @access public * @param string $name 资源地址 * @return object * @throws ClassNotFoundException */ public function controller(string $name) { $suffix = $this->rule->config('controller_suffix') ? 'Controller' : ''; $controllerLayer = $this->rule->config('controller_layer') ?: 'controller'; $emptyController = $this->rule->config('empty_controller') ?: 'Error'; $class = $this->app->parseClass($controllerLayer, $name . $suffix); if (class_exists($class)) { return $this->app->make($class, [], true); } elseif ($emptyController && class_exists($emptyClass = $this->app->parseClass($controllerLayer, $emptyController . $suffix))) { return $this->app->make($emptyClass, [], true); } throw new ClassNotFoundException('class not exists:' . $class, $class); } }