在Laravel中,路由Route在设置域名时,理论上是不支持多域名匹配的,group()函数中的domain参数值也只接受字符串数据类型,很多开发者为了给路由匹配多个域名,可能会理所应当地为域名参数值赋上一个数组类型,或者直接赋值为一个正则表达式,比如:
[数组类型]
Route::group(['domain' => ['mob.abc.com','www.abc.com'], function () {
Route::get('/test','TestCtl@test');
});
或者
[正则表达式类型]
Route::group(['domain' => '(mob|www).abc.com'], function () {
Route::get('/test','TestCtl@test');
});
很可惜,这些方法都不能帮助开发者达到想要的效果,甚至如果采用第一种方法,传入一个数组类型的值,还会引发报错,导致全站所有路由全部失效。
如果想要实现一条路由Route匹配多个域名,其实一点也不难,只要把路由的域名值中部分用变量替代即可,比如:
Route::group(['domain' => '{sub_domain}.abc.com'], function () {
Route::get('/test','TestCtl@test');
});
以上路由,域名的子域名部分就被变量{sub_domain}
替代了,而其中的{sub_domain}
部分可以匹配任意值,但其余部分则必须精确匹配,也即,以上路由只能匹配处理来自*.abc.com
这个域名的请求。
如果想要实现多个主域名匹配,也可以把主域名部分或者后缀部分替换掉,甚至还可以将域名当做一个整体用变量替代,比如:
Route::group(['domain' => '{sub_domain}.{domain_name}.com'], function () {
Route::get('/test','TestCtl@test');
});
又比如
Route::group(['domain' => '{sub_domain}.abc.{domain_postfix}'], function () {
Route::get('/test','TestCtl@test');
});
再比如
Route::group(['domain' => '{domain}'], function () {
Route::get('/test','TestCtl@test');
});
另外,很多开发者可能还有限制部分路由访问的需求,比如一个网站有3个子域名,但只想让其中的2个访问该路由。这时,我们就需要在路由服务提供者(RouteServiceProvider)中预先为路由变量定义一个正则表达式,只让符合正则表达式的域名访问,而其他不符合的则一律拒绝,比如:
一个网站有3个域名:
mob.abc.com
www.abc.com
api.abc.com
其中,有一个路由只想让mob.abc.com
和www.abc.com
访问,这时我们就需要先在路由服务提供者(RouteServiceProvider)的boot方法中为变量{sub_domain}
定义一个正则表达式
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Route;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
class RouteServiceProvider extends ServiceProvider
{
protected $namespace = 'App\Http\Controllers';
public function boot()
{
//
$this->app['router']->pattern('sub_domain', '^(mob|www)$');
parent::boot();
}
}
然后,再按前面的方法定义路由,并在路由中使用用正则表达式规范的变量
Route::group(['domain' => '{sub_domain}.abc.com'], function () {
Route::get('/test','TestCtl@test');
});
这时,你就可以发现,该路由将只对mob.abc.com
和www.abc.com
生效,而通过api.abc.com
访问,则将会报404错误。