## 概述
在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'
]
];
~~~