我的路线设置如下:
<?php
Route::group([
'domain' => '{username}.u.'.env('APP_DOMAIN'),
], function () {
Route::get('/', 'FrontendController@site');
});
Route::group([
'domain' => env('APP_DOMAIN'),
], function () {
// Regular site routes
});
Route::group([
'domain' => '{domain}',
], function () {
Route::get('/', 'FrontendController@domain');
});
我想要实现的是允许用户拥有自己的网站,例如hello.u.domain.com,并且这些网站也通过 CNAME 到其子域的自定义域提供服务。使用上面的路由,通配符子域工作得很好。然而,自定义域路由永远不会被命中;每当访问 CNAME 到子域的自定义域时,都会使用常规站点路由。
APP_DOMAIN
与自定义域名不同,我的 $router->pattern('domain', '[a-z0-9.]+');
中有 RouteServiceProvider.php
以允许 {domain}
作为完整域名。
不幸的是,我的评论没有得到答复。这个答案假设问题是使用正常的默认路由而不是带有子域的路由。
示例:
用户正在访问 sub.website.com,但 route() 返回 website.com/blabla 而不是 sub.website.com/blabla
您可以通过在routes.php中动态创建域模式来解决这个问题
// routes.php
$url_parameters = @explode(".", $_SERVER['HTTP_HOST']);
if (count($url_parameters) == 3)
{
$pattern = '{subdomain}.{domain}.{tld}';
}
else
{
$pattern = '{domain}.{tld}';
}
Route::group(['domain' => $pattern], function () {
Route::get('/', [
'as' => 'get_index',
'uses' => 'HomeController@getIndex'
]);
}
通过使用此方法,您的路线()和控制器参数将会出现问题。
route()问题
使用此方法调用route()函数时,您将收到缺少参数的错误。 Route() 函数希望您提供 {subdomain}.{domain}.{tld} 参数。
您可以通过创建自己的路线函数来解决这个问题。我将其命名为 mdroute() (多域路由)。
function mdroute($route, $parameters = [])
{
$data = [
'domain' => \Request::route()->domain,
'tld' => \Request::route()->tld
];
$subdomain = \Request::route()->subdomain;
if ($subdomain) $data['subdomain'] = $subdomain;
// You can use mdroute('blabla', 'parameter')
// or mdroute('blabla', ['par1' => 'parameter1', 'par2' => 'parameter2'])
//
if (is_array($parameters))
{
$data = array_merge($data, $parameters);
}
else
{
$data[] = $parameters;
}
return route($route, $data);
}
控制器问题
参数 {sub}.{domain}.{tld} 始终发送到您的控制器。您无法像以前那样访问其他参数。
示例:
// Domain = sub.webite.com
// Your route
//
Route::get('/post/{id}/{param2}', [
'uses' => 'PostController@getIndex'
]);
// PostController
//
public function getIndex($id, $param2)
{
// $id will be 'sub'
// $param2 will be 'website'
}
您可以通过 Request 对象访问您的参数来解决此问题。
public function getIndex(Request $request)
{
$id = $request->id;
$param2 = $reqeust->param2;
}
整个域不能有通配符,至少不能有一个通配符。您可以执行以下操作:
Route::group([
'domain' => '{domain}.{suffix}',
], function () {
Route::get('/', 'FrontendController@domain');
});
只需确保该组是路由文件中的最后一个组,它将充当域上的后备组,并将服务与任何先前域都不匹配的请求。
我还建议使用这个包,它可能对你想做的事情有帮助。
我自己已经回答了(至少部分):使用子域和域通配符在 Laravel 中创建路由
简而言之,你不能将整个域作为路由文件中的参数。相反,您分配一个中间件来检查当前域,将其与预定义的允许用户域列表进行匹配,并基于此做出一些决定(例如,在控制器中点击什么方法)。
考虑:
Route::group([
'middleware' => 'domain-check',
], function () {
Route::get('/', 'FrontendController@handle');
});
然后在你的 FrontendController 中:
public function handle(Request $request)
{
// Information about the current user/domain is here
$request->client;
// An example - let's imagine that client object contains a view ID
return response()->view($request->client->view);
}