Server : nginx/1.20.1 System : Linux iZ2ze9ojcl78uluczwag69Z 4.18.0-240.22.1.el8_3.x86_64 #1 SMP Thu Apr 8 19:01:30 UTC 2021 x86_64 User : www ( 1000) PHP Version : 7.3.28 Disable Function : passthru,exec,system,chroot,chgrp,chown,shell_exec,popen,proc_open,pcntl_exec,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,imap_open,apache_setenv Directory : /www/wwwroot/0531yanglao.com/vendor/topthink/framework/src/think/route/dispatch/ |
<?php // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- // | Copyright (c) 2006~2021 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- // | Author: liu21st <liu21st@gmail.com> // +---------------------------------------------------------------------- declare (strict_types = 1); namespace think\route\dispatch; use ReflectionClass; use ReflectionException; use ReflectionMethod; 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); $result = $this->dispatch; if (is_string($result)) { $result = explode('/', $result); } // 获取控制器名 $controller = strip_tags($result[0] ?: $this->rule->config('default_controller')); if (strpos($controller, '.')) { $pos = strrpos($controller, '.'); $this->controller = substr($controller, 0, $pos) . '.' . Str::studly(substr($controller, $pos + 1)); } else { $this->controller = Str::studly($controller); } // 获取操作名 $this->actionName = strip_tags($result[1] ?: $this->rule->config('default_action')); // 设置当前请求的控制器、操作 $this->request ->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()); } // 注册控制器中间件 $this->registerControllerMiddleware($instance); return $this->app->middleware->pipeline('controller') ->send($this->request) ->then(function () use ($instance) { // 获取当前操作名 $suffix = $this->rule->config('action_suffix'); $action = $this->actionName . $suffix; if (is_callable([$instance, $action])) { $vars = $this->request->param(); try { $reflect = new ReflectionMethod($instance, $action); // 严格获取当前操作方法名 $actionName = $reflect->getName(); if ($suffix) { $actionName = substr($actionName, 0, -strlen($suffix)); } $this->request->setAction($actionName); } catch (ReflectionException $e) { $reflect = new ReflectionMethod($instance, '__call'); $vars = [$action, $vars]; $this->request->setAction($action); } } else { // 操作不存在 throw new HttpException(404, 'method not exists:' . get_class($instance) . '->' . $action . '()'); } $data = $this->app->invokeReflectMethod($instance, $reflect, $vars); return $this->autoResponse($data); }); } protected function parseActions($actions) { return array_map(function ($item) { return strtolower($item); }, is_string($actions) ? explode(",", $actions) : $actions); } /** * 使用反射机制注册控制器中间件 * @access public * @param object $controller 控制器实例 * @return void */ protected function registerControllerMiddleware($controller): void { $class = new ReflectionClass($controller); if ($class->hasProperty('middleware')) { $reflectionProperty = $class->getProperty('middleware'); $reflectionProperty->setAccessible(true); $middlewares = $reflectionProperty->getValue($controller); $action = $this->request->action(true); foreach ($middlewares as $key => $val) { if (!is_int($key)) { $middleware = $key; $options = $val; } elseif (isset($val['middleware'])) { $middleware = $val['middleware']; $options = $val['options'] ?? []; } else { $middleware = $val; $options = []; } if (isset($options['only']) && !in_array($action, $this->parseActions($options['only']))) { continue; } elseif (isset($options['except']) && in_array($action, $this->parseActions($options['except']))) { continue; } if (is_string($middleware) && strpos($middleware, ':')) { $middleware = explode(':', $middleware); if (count($middleware) > 1) { $middleware = [$middleware[0], array_slice($middleware, 1)]; } } $this->app->middleware->controller($middleware); } } } /** * 实例化访问控制器 * @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); } }