## 概述
在ThinkPHP5中,可以很轻松的实现将模块部署到某个域名规则(包括完整域名、二级域名、三级域名和泛域名),而不需要分开不同的应用入口文件。
要使用域名部署,首先需要在应用的公共配置文件中开启
~~~
'url_domain_deploy'=>true,
~~~
## 域名部署
开启域名部署后,可以在应用配置文件中设置`url_domain_rules`或者通过下面的方法动态设置。
### 注册域名部署规则
可以用Route类的domain方法注册子域名部署规则:
~~~
\think\Route::domain('域名规则','部署规则');
~~~
或者批量注册:
~~~
\think\Route::domain(['域名规则'=>'部署规则',...]);
~~~
### 域名规则
域名规则的定义可以支持完整域名(或者IP)、二级域名(包括泛二级域名)和三级域名(包括泛三级域名),例如:
~~~
\think\Route::domain('doc.thinkphp.cn','home/doc'); // 部署完整域名doc.thinkphp.cn到应用的home模块的doc控制器
\think\Route::domain('202.65.34.5','admin'); // IP地址202.65.34.5访问部署到admin模块
\think\Route::domain('blog','home/blog'); // 部署blog二级域名到home模块的blog控制器
\think\Route::domain('*','home'); // 泛二级域名部署到home模块
\think\Route::domain('admin.blog','admin'); // 三级域名部署到admin模块
\think\Route::domain('*.user','user'); // 泛三级域名部署到user模块
~~~
或者采用批量注册方式定义:
~~~
\think\Route::domain([
'doc.thinkphp.cn' => 'home/doc',
'202.65.34.5' => 'admin',
'blog' => 'home/blog',
'*' => 'home',
'admin.blog' => 'admin',
'*.user' => 'user'
]);
~~~
注意域名部署的优先判断级别,依次是:
#### 完整域名(或IP)-> 二级域名(或者三级域名)-> 泛三级域名 -> 泛二级域名
## 部署规则
域名的部署规则其实就是把基于部署域名的URL访问绑定到相关地址,支持下面几种类型,包括:
* 绑定到模块/控制器/操作;
* 绑定到命名空间;
* 绑定到类;
* 绑定到路由分组;
* 绑定闭包方法;
> 需要注意的是,除了了模块绑定之外的类型,将不会再进行路由检测。
### 模块绑定
也就是把域名绑定到指定的模块、控制器,甚至是操作的方式,并且还可以支持传入额外的参数,例如:
~~~
\think\Route::domain('blog','home/blog?status=1&type=1'); // 部署blog二级域名到home/blog,并传入status和type参数
~~~
上面的定义会把`$_GET['status'] = 1` 和 `$_GET['type'] = 1` 隐式传入当前的访问。
如果使用的是泛域名规则的话,可以获取泛域名的内容作为参数带入,例如:
~~~
\think\Route::domain('*.user','user?status=1&username=*'); // 泛三级域名部署到User模块
~~~
上面的定义,表示部署泛三级域名*.user到user模块,并传入 `$_GET['status'] = 1` 和 $_GET['username'] = '当前实际的泛域名'。
如果成功匹配到某个域名部署规则的话,URL地址中的解析规则将会发生变化,例如,采用域名部署之前的URL地址是:
~~~
http://www.domain.com/admin/blog/add
~~~
如果定义了
~~~
\think\Route::domain('admin','admin');
~~~
那么访问的URL地址就变成了:
~~~
http://admin.domain.com/blog/add
~~~
### 绑定到命名空间
可以支持绑定到命名空间,例如:
~~~
\think\Route::domain('admin','\app\admin\api');
~~~
把admin子域名的访问绑定到`\app\admin\api`命名空间下面,如果请求URL地址是:
~~~
http://admin.domain.com/index.php/user/info/id/8
~~~
那么执行的其实就是 \app\admin\api\user 类的info方法,并且传入参数id=8
### 绑定到类
支持直接绑定到类,例如:
~~~
\think\Route::domain('admin','@\app\admin\api\user');
~~~
把admin子域名的访问绑定到`\app\admin\api\user`类下面,如果请求URL地址是:
~~~
http://admin.domain.com/index.php/info/id/8
~~~
那么执行的其实就是和上面相同的方法。
### 绑定到路由分组
如果你定义了较多的分组路由,也可以支持把域名绑定到某个路由分组,例如:
~~~
\think\Route::domain('admin','[admin]');
~~~
绑定之后,检测路由的时候只会检测该分组下面的路由。
### 闭包支持
域名的部署规则支持闭包函数,例如:
~~~
\think\Route::domain('*',function(){
exit('非法访问!');
});
~~~
部署规则中的闭包函数不支持外部传入参数,但可以支持默认参数。
如果要进行路由劫持,可以在闭包函数里面返回数组,例如:
~~~
\think\Route::domain('user',function(){
// 表示路由到user模块的index控制器
return ['type'=>'module','module'=>'user/index'];
});
~~~
## 配置文件
也可以直接在应用配置文件中直接设置如下:
~~~
'url_domain_deploy'=>true,
~~~
在route.php文件中添加域名部署定义如下:
~~~
return [
'__domain__'=>[
'doc.thinkphp.cn' => 'home/doc',
'202.65.34.5' => 'admin',
'blog' => 'home/blog',
'*' => 'home',
'admin.blog' => 'admin',
'*.user' => 'user'
]
];
~~~