Dispatcher.php 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. <?php
  2. namespace Qii\Controller;
  3. class Dispatcher
  4. {
  5. public $request;
  6. public function __construct()
  7. {
  8. }
  9. public function setRequest(\Qii\Request\Http $request)
  10. {
  11. $this->request = $request;
  12. return $this;
  13. }
  14. /**
  15. * 转发
  16. * @param string $controller
  17. * @param string $action
  18. * @return mixed
  19. */
  20. public function dispatch($controller = '', $action = '')
  21. {
  22. $args = func_get_args();
  23. $controller = $controller != '' ? $controller : $this->request->getControllerName();
  24. $action = $action != '' ? $action : $this->request->getActionName();
  25. $controllerName = \Qii\Config\Register::get(\Qii\Consts\Config::APP_DEFAULT_CONTROLLER_PREFIX) . '_' . $controller;
  26. $funcArgs = array();
  27. if (count($args) > 2) {
  28. $funcArgs = array_slice($args, 2);
  29. }
  30. array_unshift($funcArgs, $controllerName);
  31. $psr4 = \Qii\Autoloader\Psr4::getInstance();
  32. $controllerCls = call_user_func_array(array($psr4, 'loadClass'), $funcArgs);
  33. $controllerCls->setRequest($this->request);
  34. $controllerCls->controller = $controllerCls;
  35. $controllerCls->controllerId = $controller;
  36. $controllerCls->actionId = $action;
  37. //查看是否设置了当前action的对应关系,如果设置了就走对应关系里边的,否则走当前类中的
  38. if ($controllerCls->actions && isset($controllerCls->actions[$action]) && $controllerCls->actions[$action]) {
  39. $actionArgs = array();
  40. $actionArgs[] = $controllerCls->actions[$action];
  41. //$actionArgs[] = $controllerCls;
  42. //$actionArgs[] = $action;
  43. $actionCls = call_user_func_array(array($psr4, 'loadClass'), $actionArgs);
  44. $actionCls->setRequest($this->request);
  45. $actionCls->controller = $controllerCls;
  46. $actionCls->actionId = $action;
  47. $actionCls->controllerId = $controllerCls->controllerId;
  48. //支持多个action对应到同一个文件,如果对应的文件中存在指定的方法就直接调用
  49. if (method_exists($actionCls, $action . \Qii\Config\Register::get(\Qii\Consts\Config::APP_DEFAULT_ACTION_SUFFIX))) {
  50. return call_user_func_array(array($actionCls, $action. \Qii\Config\Register::get(\Qii\Consts\Config::APP_DEFAULT_ACTION_SUFFIX)), $funcArgs);
  51. }
  52. if (!method_exists($actionCls, 'run')) {
  53. throw new \Qii\Exceptions\MethodNotFound(\Qii::i(1101, $controllerCls->actions[$action] . '->run'), __LINE__);
  54. }
  55. return call_user_func_array(array($actionCls, 'run'), $funcArgs);
  56. } else {
  57. array_shift($funcArgs);
  58. $actionName = $action . \Qii\Config\Register::get(\Qii\Consts\Config::APP_DEFAULT_ACTION_SUFFIX);
  59. if (!method_exists($controllerCls, $actionName) && !method_exists($controllerCls, '__call')) {
  60. throw new \Qii\Exceptions\MethodNotFound(\Qii::i(1101, $controller . '->' . $actionName), __LINE__);
  61. }
  62. return call_user_func_array(array($controllerCls, $actionName), $funcArgs);
  63. }
  64. }
  65. }