Domain.php 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | ThinkPHP [ WE CAN DO IT JUST THINK ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8. // +----------------------------------------------------------------------
  9. // | Author: liu21st <liu21st@gmail.com>
  10. // +----------------------------------------------------------------------
  11. namespace think\route;
  12. use think\Container;
  13. use think\Loader;
  14. use think\Route;
  15. use think\route\dispatch\Callback as CallbackDispatch;
  16. use think\route\dispatch\Controller as ControllerDispatch;
  17. use think\route\dispatch\Module as ModuleDispatch;
  18. class Domain extends RuleGroup
  19. {
  20. /**
  21. * 架构函数
  22. * @access public
  23. * @param Route $router 路由对象
  24. * @param string $name 路由域名
  25. * @param mixed $rule 域名路由
  26. * @param array $option 路由参数
  27. * @param array $pattern 变量规则
  28. */
  29. public function __construct(Route $router, $name = '', $rule = null, $option = [], $pattern = [])
  30. {
  31. $this->router = $router;
  32. $this->domain = $name;
  33. $this->option = $option;
  34. $this->rule = $rule;
  35. $this->pattern = $pattern;
  36. }
  37. /**
  38. * 检测域名路由
  39. * @access public
  40. * @param Request $request 请求对象
  41. * @param string $url 访问地址
  42. * @param bool $completeMatch 路由是否完全匹配
  43. * @return Dispatch|false
  44. */
  45. public function check($request, $url, $completeMatch = false)
  46. {
  47. // 检测别名路由
  48. $result = $this->checkRouteAlias($request, $url);
  49. if (false !== $result) {
  50. return $result;
  51. }
  52. // 检测URL绑定
  53. $result = $this->checkUrlBind($request, $url);
  54. if (!empty($this->option['append'])) {
  55. $request->setRouteVars($this->option['append']);
  56. unset($this->option['append']);
  57. }
  58. if (false !== $result) {
  59. return $result;
  60. }
  61. // 添加域名中间件
  62. if (!empty($this->option['middleware'])) {
  63. Container::get('middleware')->import($this->option['middleware']);
  64. unset($this->option['middleware']);
  65. }
  66. return parent::check($request, $url, $completeMatch);
  67. }
  68. /**
  69. * 设置路由绑定
  70. * @access public
  71. * @param string $bind 绑定信息
  72. * @return $this
  73. */
  74. public function bind($bind)
  75. {
  76. $this->router->bind($bind, $this->domain);
  77. return $this;
  78. }
  79. /**
  80. * 检测路由别名
  81. * @access private
  82. * @param Request $request
  83. * @param string $url URL地址
  84. * @return Dispatch|false
  85. */
  86. private function checkRouteAlias($request, $url)
  87. {
  88. $alias = strpos($url, '|') ? strstr($url, '|', true) : $url;
  89. $item = $this->router->getAlias($alias);
  90. return $item ? $item->check($request, $url) : false;
  91. }
  92. /**
  93. * 检测URL绑定
  94. * @access private
  95. * @param Request $request
  96. * @param string $url URL地址
  97. * @return Dispatch|false
  98. */
  99. private function checkUrlBind($request, $url)
  100. {
  101. $bind = $this->router->getBind($this->domain);
  102. if (!empty($bind)) {
  103. $this->parseBindAppendParam($bind);
  104. // 记录绑定信息
  105. Container::get('app')->log('[ BIND ] ' . var_export($bind, true));
  106. // 如果有URL绑定 则进行绑定检测
  107. $type = substr($bind, 0, 1);
  108. $bind = substr($bind, 1);
  109. $bindTo = [
  110. '\\' => 'bindToClass',
  111. '@' => 'bindToController',
  112. ':' => 'bindToNamespace',
  113. ];
  114. if (isset($bindTo[$type])) {
  115. return $this->{$bindTo[$type]}($request, $url, $bind);
  116. }
  117. }
  118. return false;
  119. }
  120. protected function parseBindAppendParam(&$bind)
  121. {
  122. if (false !== strpos($bind, '?')) {
  123. list($bind, $query) = explode('?', $bind);
  124. parse_str($query, $vars);
  125. $this->append($vars);
  126. }
  127. }
  128. /**
  129. * 绑定到类
  130. * @access protected
  131. * @param Request $request
  132. * @param string $url URL地址
  133. * @param string $class 类名(带命名空间)
  134. * @return CallbackDispatch
  135. */
  136. protected function bindToClass($request, $url, $class)
  137. {
  138. $array = explode('|', $url, 2);
  139. $action = !empty($array[0]) ? $array[0] : $this->router->config('default_action');
  140. $param = [];
  141. if (!empty($array[1])) {
  142. $this->parseUrlParams($request, $array[1], $param);
  143. }
  144. return new CallbackDispatch($request, $this, [$class, $action], $param);
  145. }
  146. /**
  147. * 绑定到命名空间
  148. * @access protected
  149. * @param Request $request
  150. * @param string $url URL地址
  151. * @param string $namespace 命名空间
  152. * @return CallbackDispatch
  153. */
  154. protected function bindToNamespace($request, $url, $namespace)
  155. {
  156. $array = explode('|', $url, 3);
  157. $class = !empty($array[0]) ? $array[0] : $this->router->config('default_controller');
  158. $method = !empty($array[1]) ? $array[1] : $this->router->config('default_action');
  159. $param = [];
  160. if (!empty($array[2])) {
  161. $this->parseUrlParams($request, $array[2], $param);
  162. }
  163. return new CallbackDispatch($request, $this, [$namespace . '\\' . Loader::parseName($class, 1), $method], $param);
  164. }
  165. /**
  166. * 绑定到控制器类
  167. * @access protected
  168. * @param Request $request
  169. * @param string $url URL地址
  170. * @param string $controller 控制器名 (支持带模块名 index/user )
  171. * @return ControllerDispatch
  172. */
  173. protected function bindToController($request, $url, $controller)
  174. {
  175. $array = explode('|', $url, 2);
  176. $action = !empty($array[0]) ? $array[0] : $this->router->config('default_action');
  177. $param = [];
  178. if (!empty($array[1])) {
  179. $this->parseUrlParams($request, $array[1], $param);
  180. }
  181. return new ControllerDispatch($request, $this, $controller . '/' . $action, $param);
  182. }
  183. /**
  184. * 绑定到模块/控制器
  185. * @access protected
  186. * @param Request $request
  187. * @param string $url URL地址
  188. * @param string $controller 控制器类名(带命名空间)
  189. * @return ModuleDispatch
  190. */
  191. protected function bindToModule($request, $url, $controller)
  192. {
  193. $array = explode('|', $url, 2);
  194. $action = !empty($array[0]) ? $array[0] : $this->router->config('default_action');
  195. $param = [];
  196. if (!empty($array[1])) {
  197. $this->parseUrlParams($request, $array[1], $param);
  198. }
  199. return new ModuleDispatch($request, $this, $controller . '/' . $action, $param);
  200. }
  201. }