From 81a2222143be287b97bc26be9eda8141491a2bcf Mon Sep 17 00:00:00 2001 From: thinkphp Date: Tue, 2 Aug 2016 16:53:05 +0800 Subject: [PATCH] =?UTF-8?q?Route=E7=B1=BB=E7=9A=84domain=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E5=92=8C=E5=9F=9F=E5=90=8D=E8=B7=AF=E7=94=B1=E5=8A=A8=E6=80=81?= =?UTF-8?q?=E6=B3=A8=E5=86=8C=E6=9C=BA=E5=88=B6=E8=B0=83=E6=95=B4=20?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3Connction=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- library/think/Route.php | 149 ++++++++++++--------- library/think/db/Connection.php | 5 +- tests/thinkphp/library/think/routeTest.php | 10 +- 3 files changed, 96 insertions(+), 68 deletions(-) diff --git a/library/think/Route.php b/library/think/Route.php index bb23110a..9ac74d33 100644 --- a/library/think/Route.php +++ b/library/think/Route.php @@ -65,6 +65,9 @@ class Route // 路由命名标识(用于快速URL生成) private static $name = []; // 当前子域名绑定 + private static $domainBind; + private static $domainRule; + // 当前域名 private static $domain; /** @@ -96,13 +99,32 @@ class Route { if (is_array($domain)) { foreach ($domain as $key => $item) { - self::$rules['domain'][$key] = [$item, $option, $pattern]; + self::domain($key, $item, $option, $pattern); } } else { - self::$rules['domain'][$domain] = [$rule, $option, $pattern]; + if ($rule instanceof \Closure) { + // 执行闭包 + self::setDomain($domain); + call_user_func_array($rule, []); + self::setDomain(null); + } elseif (is_array($rule)) { + self::setDomain($domain); + self::group('', function () use ($rule) { + // 动态注册域名的路由规则 + self::registerRules($rule); + }, $option, $pattern); + self::setDomain(null); + } else { + self::$rules['domain'][$domain]['[bind]'] = [$rule, $option, $pattern]; + } } } + private static function setDomain($domain) + { + self::$domain = $domain; + } + /** * 设置路由绑定 * @access public @@ -276,16 +298,28 @@ class Route if ('*' != $type) { $option['method'] = $type; } - self::$rules['*'][$group]['rule'][] = ['rule' => $rule, 'route' => $route, 'var' => $vars, 'option' => $option, 'pattern' => $pattern]; + if (self::$domain) { + self::$rules['domain'][self::$domain]['*'][$group]['rule'][] = ['rule' => $rule, 'route' => $route, 'var' => $vars, 'option' => $option, 'pattern' => $pattern]; + } else { + self::$rules['*'][$group]['rule'][] = ['rule' => $rule, 'route' => $route, 'var' => $vars, 'option' => $option, 'pattern' => $pattern]; + } } else { if ('*' != $type && isset(self::$rules['*'][$rule])) { unset(self::$rules['*'][$rule]); } - self::$rules[$type][$rule] = ['rule' => $rule, 'route' => $route, 'var' => $vars, 'option' => $option, 'pattern' => $pattern]; + if (self::$domain) { + self::$rules['domain'][self::$domain][$type][$rule] = ['rule' => $rule, 'route' => $route, 'var' => $vars, 'option' => $option, 'pattern' => $pattern]; + } else { + self::$rules[$type][$rule] = ['rule' => $rule, 'route' => $route, 'var' => $vars, 'option' => $option, 'pattern' => $pattern]; + } if ('*' == $type) { // 注册路由快捷方式 foreach (['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS'] as $method) { - self::$rules[$method][$rule] = true; + if (self::$domain) { + self::$rules['domain'][self::$domain][$method][$rule] = true; + } else { + self::$rules[$method][$rule] = true; + } } } } @@ -636,10 +670,11 @@ class Route * 检测子域名部署 * @access public * @param Request $request Request请求对象 + * @param array $rules 当前路由规则 * @param string $method 请求类型 * @return void */ - public static function checkDomain($request, $method = 'GET') + public static function checkDomain($request, &$rules, $method = 'GET') { // 域名规则 $rules = self::$rules['domain']; @@ -684,55 +719,45 @@ class Route } } if (!empty($item)) { - self::$domain = true; - // 解析子域名部署规则 - list($rule, $option, $pattern) = $item; - if (!empty($option['https']) && !$request->isSsl()) { - // https检测 - throw new HttpException(404, 'must use https request:' . $host); - } - if ($rule instanceof \Closure) { - // 执行闭包 - $reflect = new \ReflectionFunction($rule); - self::$bind = $reflect->invokeArgs([]); - return; - } elseif (is_array($rule)) { - // 清空当前路由规则 - self::$rules[$method] = []; - self::$rules['*'] = []; - self::group('', function () use ($rule) { - // 动态注册域名的路由规则 - self::registerRules($rule); - }, $option, $pattern); - return; - } - - if (strpos($rule, '?')) { - // 传入其它参数 - $array = parse_url($rule); - $result = $array['path']; - parse_str($array['query'], $params); - if (isset($panDomain)) { - $pos = array_search('*', $params); - if (false !== $pos) { - // 泛域名作为参数 - $params[$pos] = $panDomain; - } + if (isset($item['[bind]'])) { + // 解析子域名部署规则 + list($rule, $option, $pattern) = $item['[bind]']; + if (!empty($option['https']) && !$request->isSsl()) { + // https检测 + throw new HttpException(404, 'must use https request:' . $host); } - $_GET = array_merge($_GET, $params); - } else { - $result = $rule; - } - if (0 === strpos($result, '\\')) { - // 绑定到命名空间 例如 \app\index\behavior - self::$bind = ['type' => 'namespace', 'namespace' => $result]; - } elseif (0 === strpos($result, '@')) { - // 绑定到类 例如 @app\index\controller\User - self::$bind = ['type' => 'class', 'class' => substr($result, 1)]; + if (strpos($rule, '?')) { + // 传入其它参数 + $array = parse_url($rule); + $result = $array['path']; + parse_str($array['query'], $params); + if (isset($panDomain)) { + $pos = array_search('*', $params); + if (false !== $pos) { + // 泛域名作为参数 + $params[$pos] = $panDomain; + } + } + $_GET = array_merge($_GET, $params); + } else { + $result = $rule; + } + + if (0 === strpos($result, '\\')) { + // 绑定到命名空间 例如 \app\index\behavior + self::$bind = ['type' => 'namespace', 'namespace' => $result]; + } elseif (0 === strpos($result, '@')) { + // 绑定到类 例如 @app\index\controller\User + self::$bind = ['type' => 'class', 'class' => substr($result, 1)]; + } else { + // 绑定到模块/控制器 例如 index/user + self::$bind = ['type' => 'module', 'module' => $result]; + } + self::$domainBind = true; } else { - // 绑定到模块/控制器 例如 index/user - self::$bind = ['type' => 'module', 'module' => $result]; + self::$domainRule = $item; + $rules = isset($item[$method]) ? $item[$method] : $item['*']; } } } @@ -762,13 +787,12 @@ class Route } } $method = $request->method(); - // 检测域名部署 - if ($checkDomain) { - self::checkDomain($request, $method); - } // 获取当前请求类型的路由规则 $rules = self::$rules[$method]; - + // 检测域名部署 + if ($checkDomain) { + self::checkDomain($request, $rules, $method); + } // 检测URL绑定 $return = self::checkUrlBind($url, $rules, $depr); if (false !== $return) { @@ -781,7 +805,7 @@ class Route // 静态路由规则检测 $rule = $rules[$url]; if (true === $rule) { - $rule = self::$rules['*'][$url]; + $rule = self::getRouteExpress($url); } if (!empty($rule['route'])) { return self::parseRule($url, $rule['route'], $url, $rule['option']); @@ -795,6 +819,11 @@ class Route return false; } + private static function getRouteExpress($key) + { + return self::$domainRule ? self::$domainRule['*'][$key] : self::$rules['*'][$key]; + } + /** * 检测路由规则 * @access private @@ -809,7 +838,7 @@ class Route { foreach ($rules as $key => $item) { if (true === $item) { - $item = self::$rules['*'][$key]; + $item = self::getRouteExpress($key); } if (!isset($item['rule'])) { continue; @@ -925,7 +954,7 @@ class Route return self::bindToNamespace($url, $bind, $depr); case 'module': // 如果有模块/控制器绑定 针对路由到 模块/控制器 有效 - $url = (empty(self::$domain) ? $bind . '/' : '') . ltrim($url, '/'); + $url = (empty(self::$domainBind) ? $bind . '/' : '') . ltrim($url, '/'); break; } } diff --git a/library/think/db/Connection.php b/library/think/db/Connection.php index 8987391c..b92aea6d 100644 --- a/library/think/db/Connection.php +++ b/library/think/db/Connection.php @@ -251,10 +251,9 @@ abstract class Connection public function connect(array $config = [], $linkNum = 0, $autoConnection = false) { if (!isset($this->links[$linkNum])) { - if ($config) { - $this->setConfig($config); + if (!$config) { + $config = $this->config; } - $config = $this->config; // 连接参数 if (isset($config['params']) && is_array($config['params'])) { $params = $config['params'] + $this->params; diff --git a/tests/thinkphp/library/think/routeTest.php b/tests/thinkphp/library/think/routeTest.php index e9c6fa2e..db3d6995 100644 --- a/tests/thinkphp/library/think/routeTest.php +++ b/tests/thinkphp/library/think/routeTest.php @@ -268,22 +268,22 @@ class routeTest extends \PHPUnit_Framework_TestCase { $request = Request::create('http://subdomain.thinkphp.cn'); Route::domain('subdomain.thinkphp.cn', 'sub?abc=test&status=1'); - Route::checkDomain($request); - $this->assertEquals('sub?abc=test&status=1', Route::rules('domain')['subdomain.thinkphp.cn'][0]); + $rules = Route::rules('GET'); + Route::checkDomain($request, $rules); $this->assertEquals('sub', Route::getbind('module')); $this->assertEquals('test', $_GET['abc']); $this->assertEquals(1, $_GET['status']); Route::domain('subdomain.thinkphp.cn', function () {return ['type' => 'module', 'module' => 'sub2'];}); - Route::checkDomain($request); + Route::checkDomain($request, $rules); $this->assertEquals('sub2', Route::getbind('module')); Route::domain('subdomain.thinkphp.cn', '\app\index\controller'); - Route::checkDomain($request); + Route::checkDomain($request, $rules); $this->assertEquals('\app\index\controller', Route::getbind('namespace')); Route::domain(['subdomain.thinkphp.cn' => '@\app\index\controller\blog']); - Route::checkDomain($request); + Route::checkDomain($request, $rules); $this->assertEquals('\app\index\controller\blog', Route::getbind('class')); }