Dispatcher.php 3.9 KB

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