991 lines
26 KiB
PHP
Executable File
991 lines
26 KiB
PHP
Executable File
<?php
|
|
// +----------------------------------------------------------------------
|
|
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
|
// +----------------------------------------------------------------------
|
|
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
|
// +----------------------------------------------------------------------
|
|
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
|
// +----------------------------------------------------------------------
|
|
// | Author: liu21st <liu21st@gmail.com>
|
|
// +----------------------------------------------------------------------
|
|
|
|
namespace think;
|
|
|
|
use think\exception\RouteNotFoundException;
|
|
use think\route\AliasRule;
|
|
use think\route\dispatch\Url as UrlDispatch;
|
|
use think\route\Domain;
|
|
use think\route\Resource;
|
|
use think\route\RuleGroup;
|
|
use think\route\RuleItem;
|
|
|
|
class Route
|
|
{
|
|
/**
|
|
* REST定义
|
|
* @var array
|
|
*/
|
|
protected $rest = [
|
|
'index' => ['get', '', 'index'],
|
|
'create' => ['get', '/create', 'create'],
|
|
'edit' => ['get', '/<id>/edit', 'edit'],
|
|
'read' => ['get', '/<id>', 'read'],
|
|
'save' => ['post', '', 'save'],
|
|
'update' => ['put', '/<id>', 'update'],
|
|
'delete' => ['delete', '/<id>', 'delete'],
|
|
];
|
|
|
|
/**
|
|
* 请求方法前缀定义
|
|
* @var array
|
|
*/
|
|
protected $methodPrefix = [
|
|
'get' => 'get',
|
|
'post' => 'post',
|
|
'put' => 'put',
|
|
'delete' => 'delete',
|
|
'patch' => 'patch',
|
|
];
|
|
|
|
/**
|
|
* 应用对象
|
|
* @var App
|
|
*/
|
|
protected $app;
|
|
|
|
/**
|
|
* 请求对象
|
|
* @var Request
|
|
*/
|
|
protected $request;
|
|
|
|
/**
|
|
* 当前HOST
|
|
* @var string
|
|
*/
|
|
protected $host;
|
|
|
|
/**
|
|
* 当前域名
|
|
* @var string
|
|
*/
|
|
protected $domain;
|
|
|
|
/**
|
|
* 当前分组对象
|
|
* @var RuleGroup
|
|
*/
|
|
protected $group;
|
|
|
|
/**
|
|
* 配置参数
|
|
* @var array
|
|
*/
|
|
protected $config = [];
|
|
|
|
/**
|
|
* 路由绑定
|
|
* @var array
|
|
*/
|
|
protected $bind = [];
|
|
|
|
/**
|
|
* 域名对象
|
|
* @var array
|
|
*/
|
|
protected $domains = [];
|
|
|
|
/**
|
|
* 跨域路由规则
|
|
* @var RuleGroup
|
|
*/
|
|
protected $cross;
|
|
|
|
/**
|
|
* 路由别名
|
|
* @var array
|
|
*/
|
|
protected $alias = [];
|
|
|
|
/**
|
|
* 路由是否延迟解析
|
|
* @var bool
|
|
*/
|
|
protected $lazy = true;
|
|
|
|
/**
|
|
* 路由是否测试模式
|
|
* @var bool
|
|
*/
|
|
protected $isTest;
|
|
|
|
/**
|
|
* (分组)路由规则是否合并解析
|
|
* @var bool
|
|
*/
|
|
protected $mergeRuleRegex = true;
|
|
|
|
/**
|
|
* 路由解析自动搜索多级控制器
|
|
* @var bool
|
|
*/
|
|
protected $autoSearchController = true;
|
|
|
|
public function __construct(App $app, array $config = [])
|
|
{
|
|
$this->app = $app;
|
|
$this->request = $app['request'];
|
|
$this->config = $config;
|
|
|
|
$this->host = $this->request->host(true) ?: $config['app_host'];
|
|
|
|
$this->setDefaultDomain();
|
|
}
|
|
|
|
public function config($name = null)
|
|
{
|
|
if (is_null($name)) {
|
|
return $this->config;
|
|
}
|
|
|
|
return isset($this->config[$name]) ? $this->config[$name] : null;
|
|
}
|
|
|
|
/**
|
|
* 配置
|
|
* @access public
|
|
* @param array $config
|
|
* @return void
|
|
*/
|
|
public function setConfig(array $config = [])
|
|
{
|
|
$this->config = array_merge($this->config, array_change_key_case($config));
|
|
}
|
|
|
|
public static function __make(App $app, Config $config)
|
|
{
|
|
$config = $config->pull('app');
|
|
$route = new static($app, $config);
|
|
|
|
$route->lazy($config['url_lazy_route'])
|
|
->autoSearchController($config['controller_auto_search'])
|
|
->mergeRuleRegex($config['route_rule_merge']);
|
|
|
|
return $route;
|
|
}
|
|
|
|
/**
|
|
* 设置路由的请求对象实例
|
|
* @access public
|
|
* @param Request $request 请求对象实例
|
|
* @return void
|
|
*/
|
|
public function setRequest($request)
|
|
{
|
|
$this->request = $request;
|
|
}
|
|
|
|
/**
|
|
* 设置路由域名及分组(包括资源路由)是否延迟解析
|
|
* @access public
|
|
* @param bool $lazy 路由是否延迟解析
|
|
* @return $this
|
|
*/
|
|
public function lazy($lazy = true)
|
|
{
|
|
$this->lazy = $lazy;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* 设置路由为测试模式
|
|
* @access public
|
|
* @param bool $test 路由是否测试模式
|
|
* @return void
|
|
*/
|
|
public function setTestMode($test)
|
|
{
|
|
$this->isTest = $test;
|
|
}
|
|
|
|
/**
|
|
* 检查路由是否为测试模式
|
|
* @access public
|
|
* @return bool
|
|
*/
|
|
public function isTest()
|
|
{
|
|
return $this->isTest;
|
|
}
|
|
|
|
/**
|
|
* 设置路由域名及分组(包括资源路由)是否合并解析
|
|
* @access public
|
|
* @param bool $merge 路由是否合并解析
|
|
* @return $this
|
|
*/
|
|
public function mergeRuleRegex($merge = true)
|
|
{
|
|
$this->mergeRuleRegex = $merge;
|
|
$this->group->mergeRuleRegex($merge);
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* 设置路由自动解析是否搜索多级控制器
|
|
* @access public
|
|
* @param bool $auto 是否自动搜索多级控制器
|
|
* @return $this
|
|
*/
|
|
public function autoSearchController($auto = true)
|
|
{
|
|
$this->autoSearchController = $auto;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* 初始化默认域名
|
|
* @access protected
|
|
* @return void
|
|
*/
|
|
protected function setDefaultDomain()
|
|
{
|
|
// 默认域名
|
|
$this->domain = $this->host;
|
|
|
|
// 注册默认域名
|
|
$domain = new Domain($this, $this->host);
|
|
|
|
$this->domains[$this->host] = $domain;
|
|
|
|
// 默认分组
|
|
$this->group = $domain;
|
|
}
|
|
|
|
/**
|
|
* 设置当前域名
|
|
* @access public
|
|
* @param RuleGroup $group 域名
|
|
* @return void
|
|
*/
|
|
public function setGroup(RuleGroup $group)
|
|
{
|
|
$this->group = $group;
|
|
}
|
|
|
|
/**
|
|
* 获取当前分组
|
|
* @access public
|
|
* @return RuleGroup
|
|
*/
|
|
public function getGroup()
|
|
{
|
|
return $this->group;
|
|
}
|
|
|
|
/**
|
|
* 注册变量规则
|
|
* @access public
|
|
* @param string|array $name 变量名
|
|
* @param string $rule 变量规则
|
|
* @return $this
|
|
*/
|
|
public function pattern($name, $rule = '')
|
|
{
|
|
$this->group->pattern($name, $rule);
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* 注册路由参数
|
|
* @access public
|
|
* @param string|array $name 参数名
|
|
* @param mixed $value 值
|
|
* @return $this
|
|
*/
|
|
public function option($name, $value = '')
|
|
{
|
|
$this->group->option($name, $value);
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* 注册域名路由
|
|
* @access public
|
|
* @param string|array $name 子域名
|
|
* @param mixed $rule 路由规则
|
|
* @param array $option 路由参数
|
|
* @param array $pattern 变量规则
|
|
* @return Domain
|
|
*/
|
|
public function domain($name, $rule = '', $option = [], $pattern = [])
|
|
{
|
|
// 支持多个域名使用相同路由规则
|
|
$domainName = is_array($name) ? array_shift($name) : $name;
|
|
|
|
if ('*' != $domainName && false === strpos($domainName, '.')) {
|
|
$domainName .= '.' . $this->request->rootDomain();
|
|
}
|
|
|
|
if (!isset($this->domains[$domainName])) {
|
|
$domain = (new Domain($this, $domainName, $rule, $option, $pattern))
|
|
->lazy($this->lazy)
|
|
->mergeRuleRegex($this->mergeRuleRegex);
|
|
|
|
$this->domains[$domainName] = $domain;
|
|
} else {
|
|
$domain = $this->domains[$domainName];
|
|
$domain->parseGroupRule($rule);
|
|
}
|
|
|
|
if (is_array($name) && !empty($name)) {
|
|
$root = $this->request->rootDomain();
|
|
foreach ($name as $item) {
|
|
if (false === strpos($item, '.')) {
|