生产环境和开发环境下的Laravel域名路由

3

我有一个使用子域路由的 Laravel 5.2 项目,本地(homestead)和生产环境(在 AWS 上使用通配符子域路由配置的 forge)都可以运行。我的本地项目在 hosts 文件中有一个 admin.project.app 条目,并成功路由到 admin.project.app,而我的生产版本则路由到 admin.project.com

我的本地 .env 文件变量为 APP_ENV=local,而我在 forge 上的 .env 变量为 APP_ENV=production。目前为止还好。

我的问题是,我希望 Laravel 根据我是在本地运行(扩展名为 .app)还是在生产环境运行(扩展名为 .com),来解析域名,使用这种通配符路由规则:

Route::group(['domain' => 'admin.project.*'], function()
{
    Route::get('/', 'HomeController@index');

});

我遇到的问题是,Laravel、Nginx、AWS或Forge要求我明确地进行路由,这似乎完全是多余的:
if (App::environment('local')) {
    Route::group(['domain' => 'admin.project.app'], function()
    {
        Route::get('/', 'HomeController@index');

    });
}else{
    Route::group(['domain' => 'admin.project.com'], function()
    {
        Route::get('/', 'HomeController@index');

    });

}

也许我的期望值不正确 ;) 如果您能指出我可能做错的地方,我将不胜感激!
2个回答

5

一个非常简单的解决方案是使用三目运算符来确定顶级域名,并将其用于组的domain属性中:

Route::group(['domain' => 'admin.project.' . ((env('APP_ENV') == 'production') ? 'com' : 'app')], function()
{
    Route::get('/', 'HomeController@index');
});

避免代码重复并添加额外的环境变量。

我喜欢这个,也试过了,但显然Laravel不喜欢像这样动态组装域属性。我简直无法相信我必须在Laravel中拼凑一些东西来处理TLD。唉。 - Gunnar
@Gunnar 这种方法是可行的,我过去也用过,但是答案中的代码存在一个小问题。我已经更新了它,将 TLD 表达式括在括号中,否则字符串连接不会正常工作,因为算术运算符(如 .)比三元运算符 ?: 优先级高,所以在计算时它尝试将字符串与条件的结果(即 truefalse)连接起来,而不是表达式的结果(即 comapp)。 - Bogdan

2
使用路由参数{}而非*,是否会发生相同的情况?我不确定laravel路由是否支持*。
Route::group(['domain' => 'admin.project.{tld}'], function()
{
    Route::get('/', 'HomeController@index');
});

https://laravel.com/docs/5.2/routing#route-group-sub-domain-routing

如果您只是使用域名作为环境变量怎么办?在本地的env文件中添加:

APP_DOMAIN=admin.project.app

然后在路由文件中:

Route::group(['domain' => env("APP_DOMAIN","admin.project.com")],function(){

});

2
第二个解决方案很好。然而,第一个解决方案在路由有自己的参数时肯定会造成混淆。因为如果您有像这样的路由定义 Route::get('user/{name}', 'UsersController@show');,那么操作方法将接收两个参数 show($tld, $name),因此所有具有自己参数的路由操作最终都需要添加额外的 $tld 参数。 - Bogdan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接