Dispatcher.php 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  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. $this->controllerCls = call_user_func_array(array($psr4, 'loadClass'), $funcArgs);
  41. $this->controllerCls->setRequest($this->request);
  42. $this->controllerCls->controller = $this->controllerCls;
  43. $this->controllerCls->controllerId = $controller;
  44. $this->controllerCls->actionId = $action;
  45. $response = null;
  46. //查看是否设置了当前action的对应关系,如果设置了就走对应关系里边的,否则走当前类中的
  47. if ($this->controllerCls->actions && isset($this->controllerCls->actions[$action]) && $this->controllerCls->actions[$action]) {
  48. $actionArgs = array();
  49. $actionArgs[] = $this->controllerCls->actions[$action];
  50. $this->actionCls = call_user_func_array(array($psr4, 'loadClass'), $actionArgs);
  51. $this->actionCls->setRequest($this->request);
  52. $this->actionCls->controller = $this->controllerCls;
  53. $this->actionCls->actionId = $action;
  54. $this->actionCls->controllerId = $this->controllerCls->controllerId;
  55. //支持多个action对应到同一个文件,如果对应的文件中存在指定的方法就直接调用
  56. if (method_exists($this->actionCls, $action . Register::get(Consts::APP_DEFAULT_ACTION_SUFFIX))) {
  57. $this->actionCls->response = $response = call_user_func_array(array($this->actionCls, $action. Register::get(Consts::APP_DEFAULT_ACTION_SUFFIX)), $funcArgs);
  58. }
  59. if (!method_exists($this->actionCls, 'run')) {
  60. throw new \Qii\Exceptions\MethodNotFound(\Qii::i(1101, $this->controllerCls->actions[$action] . '->run'), __LINE__);
  61. }
  62. $response = call_user_func_array(array($this->actionCls, 'run'), $funcArgs);
  63. } else {
  64. array_shift($funcArgs);
  65. $actionName = $action . Register::get(Consts::APP_DEFAULT_ACTION_SUFFIX);
  66. if (!method_exists($this->controllerCls, $actionName) && !method_exists($this->controllerCls, '__call')) {
  67. throw new \Qii\Exceptions\MethodNotFound(\Qii::i(1101, $controller . '->' . $actionName), __LINE__);
  68. }
  69. $this->controllerCls->response = $response = call_user_func_array(array($this->controllerCls, $actionName), $funcArgs);
  70. }
  71. return $response;
  72. }
  73. }