Dispatcher.php 3.2 KB

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