123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- <?php
- namespace Qii\Base;
- use Qii\Autoloader\Psr4;
- use \Qii\Config\Register;
- use \Qii\Config\Consts;
- use Qii\Exceptions\MethodNotFound;
- use Qii\Request\Http;
- class Dispatcher
- {
- public $request;
- public $controllerCls = null;
- public $actionCls = null;
- private $requestMiddleWare = array();
- public function __construct()
- {
- }
- /**
- * 设置请求
- * @param Http $request 当前请求
- */
- public function setRequest(Http $request)
- {
- $this->request = $request;
- return $this;
- }
- /**
- * 设置中间件
- *
- * @param array $middleware 中间件
- * @return $this
- */
- public function setMiddleware($middleware) {
- if (!is_array($middleware)) {
- return $this;
- }
- $this->requestMiddleWare = array_merge($this->requestMiddleWare, $middleware);
- return $this;
- }
- /**
- * 获取 controller 设置的middleware
- * @param $controller
- * @return $this
- */
- public function getMiddleWare($controller)
- {
- if (method_exists($controller, 'getMiddleware')) {
- $this->requestMiddleWare = array_merge($this->requestMiddleWare, $controller->getMiddleware());
- }
- return $this;
- }
- /**
- * 整理 middleware
- * @return $this
- */
- public function gatherMiddleware()
- {
- if(count($this->requestMiddleWare) == 0) {
- return $this;
- }
- $this->requestMiddleWare = array_unique($this->requestMiddleWare);
- return $this;
- }
- /**
- * 转发
- * @param string $controller
- * @param string $action
- * @return mixed
- */
- public function dispatch($controller = '', $action = '')
- {
- $args = func_get_args();
- $controller = $controller != '' ? $controller : $this->request->getControllerName();
- $action = $action != '' ? $action : $this->request->getActionName();
- $controllerName = $controller;
- //如果controller以\开头,就不添加默认前缀 Update at 2018-05-29 13:50
- if(substr($controller,0, 1) != '\\') {
- $controllerName = Register::get(Consts::APP_DEFAULT_CONTROLLER_PREFIX) . '_' . $controller;
- }
- $funcArgs = array();
- if (count($args) > 2) {
- $funcArgs = array_slice($args, 2);
- }
- array_unshift($funcArgs, $controllerName);
- $psr4 = Psr4::getInstance();
- $controllerCls = call_user_func_array(array($psr4, 'loadClass'), $funcArgs);
- /**middleWare**/
- $this->getMiddleWare($controllerCls)->gatherMiddleware();
- $next = array_reduce($this->requestMiddleWare,function ($carry, $item){
- return function () use ($carry, $item){
- return _loadClass($item)->handle(\Qii::getInstance()->request, $carry);
- };
- }, function(){
- return true;
- })();
- if ($next === false) {
- return false;
- }
- $method = new \ReflectionMethod($this, 'dispatch');
- foreach($method->getParameters() as $property)
- {
- $param = $property->getName();
- $this->request->setParam($param, $$param);
- }
- $this->controllerCls = $controllerCls;
- $this->controllerCls->setRequest($this->request);
- $this->controllerCls->controller = $controllerCls;
- $this->controllerCls->controllerId = $controller;
- $this->controllerCls->actionId = $action;
- $realAction = $action . Register::get(Consts::APP_DEFAULT_ACTION_SUFFIX);
- //查看是否设置了当前action的对应关系,如果设置了就走对应关系里边的,否则走当前类中的
- if ($this->controllerCls->actions
- && isset($this->controllerCls->actions[$action])
- && $this->controllerCls->actions[$action]) {
- $actionArgs = array();
- $actionArgs[] = $this->controllerCls->actions[$action];
- $actionCls = call_user_func_array(array($psr4, 'loadClass'), $actionArgs);
- $this->actionCls = $actionCls;
- $this->actionCls->setRequest($this->request);
- $this->actionCls->controller = $this->controllerCls;
- $this->actionCls->actionId = $action;
- $this->actionCls->controllerId = $this->controllerCls->controllerId;
- //调用初始化方法
- if(method_exists($this->actionCls, 'initialization')) {
- call_user_func_array(array($this->actionCls, 'initialization'), array($this->actionCls));
- }
- //支持多个action对应到同一个文件,调用的方法为 ...Action,如果没有...Action就调用run
- if (method_exists($this->actionCls, $realAction)) {
- return $this->actionCls->setResponse(call_user_func_array(array($this->actionCls, $realAction), $funcArgs));
- }
- if (!method_exists($this->actionCls, 'run')) {
- throw new MethodNotFound(\Qii::i(1101, $this->controllerCls->actions[$action] . '->run'), __LINE__);
- }
- return $this->actionCls->setResponse(array($this->actionCls, 'run'), array_slice($funcArgs, 1));
- }
- if(method_exists($this->controllerCls, 'initialization')) {
- call_user_func_array(array($this->controllerCls, 'initialization'), array($this->controllerCls));
- }
- array_shift($funcArgs);
- if (!method_exists($this->controllerCls, $realAction) && !method_exists($this->controllerCls, '__call')) {
- throw new MethodNotFound(\Qii::i(1101, $controller . '->' . $realAction), __LINE__);
- }
- return $this->controllerCls->setResponse(call_user_func_array(array($this->controllerCls, $realAction), $funcArgs));
- }
- }
|