Laravel 4.1+中的环境检测

6

Laravel 4.1移除了使用域名检测应用程序运行环境的功能。阅读文档,现在建议使用主机名。然而,如果您正在团队中工作,这似乎很麻烦。每个人都需要更改bootstrap/start.php文件并添加自己的主机名才能在开发环境中运行应用程序吗?另外,如果您想在同一台机器上拥有两个不同的环境怎么办?

在Laravel 4.1+中,如何最好地检测团队中的环境?

8个回答

14

这里是来自 bootstrap/start.php 文件的设置:

$env = $app->detectEnvironment(function() use($app) {
    return getenv('ENV') ?: ($app->runningInConsole() ? 'local' : 'production');
});

与其使用默认的数组,我的方法返回一个带有三元运算符的闭包,这样我可以更加灵活地选择所需的环境。你也可以使用 switch 语句。Laravel 将读取返回值并进行配置。

使用 getenv 原生函数,我只需要监听给定的环境即可。如果我的应用在服务器上,则它将选择服务器配置。如果在本地,则会选择本地(或开发)配置。

不要忘记在 app/config 中为你的环境创建自定义目录。

还有测试环境,每次测试应用程序时都会自动选择。

Laravel 使得处理环境非常有趣。

更新:

在处理环境时,我们主要关注数据库凭据。

对于生产环境,我使用 Fortrabbit,因此在服务器上配置新应用程序时,fortrabbit 为我生成这些值。我只需要声明它们。例如 DB 或仅 database、DB_HOST 或 HOST 等等 …

在本地,这些值是你用于 localhost/mysql 设置的那些值。


受到您的回答启发,我再次阅读了文档,并发现它们实际上也建议使用 $_SERVER['ENV'] 而不是 getenv('ENV')。http://laravel.com/docs/configuration#environment-configuration - Simon Bengtsson
1
我猜getenv("ENV")指向$_SERVER["ENV"]。所以使用有效的方法。如果您喜欢,请接受答案。 - Miroslav Trninic
我没有真正理解你的更新。你从来没有设置“ENV”变量吗?甚至在本地也没有?顺便说一句,Fortrabbit看起来很棒。 - Simon Bengtsson
当然,谢谢!我确实使用特殊的配置文件夹,具体取决于应用程序当前运行的环境,但是到目前为止,我发现它们非常有限。我的大部分配置都不在版本控制中,并放置在根文件夹中的env-name.env.php文件中。 - Simon Bengtsson
1
我所寻找的是在哪里设置这个ENV变量。您可以在Apache的虚拟服务器配置中进行设置:https://dev59.com/m2gv5IYBdhLWcg3wBMSg - Aurelien
显示剩余3条评论

3

更新:

在 Laravel 5.0 中,不再需要以同样的方式进行环境检测。你可以在 .env 文件中简单地定义应用程序应在哪个环境下运行。

Laravel <= 4.2 的旧回答

我最终所做的非常接近 carousel 建议的内容。不管怎样,我想分享一下。以下是我们的 bootstrap/start.php 文件相关部分:

$env = $app->detectEnvironment(function ()
{
    if($app->runningInConsole())
        return "development";

    $validEnvironments = array("development", "staging", "production");
    if (in_array(getenv('APP_ENV'), $validEnvironments)) {
        return getenv('APP_ENV');
    }
    throw new Exception("Environment variable not set or is not valid. See developer manual for further information.");
});

这样所有团队成员都需要在某个地方声明一个环境变量。我还没有确定如果环境变量未设置应该抛出异常还是默认为生产环境更好。但是,有了上面的方法,更改起来很容易。


当使用命令行时,这种方法不起作用。Carousel的答案考虑了$app->runningInConsole()并使用了local。这允许您运行php artisan。使用您的方法我认为无法做到。 - Dustin Griffith
你实际上可以使用 artisan --env 开关来指定环境。不过,我同意 Carousel 的解决方案更好。已更新答案。 - Simon Bengtsson

1
Laravel 4.1和4.2通过在"bootstrap/start.php"文件中指定的机器名称来检测环境。
例如,在我的情况下,配置如下:
$env = $app->detectEnvironment(array(
  'local' => array('Victor.local', 'Victor-PC'),
));

这意味着Laravel将使用“本地”环境设置来适用于两台机器:“Victor.local”(Mac)和“Victor-PC”(Windows)。
这样,您可以注册多台机器以作为本地环境。其他环境也可以注册。
为了知道当前机器名称,您可以使用以下PHP代码: <?php echo gethostname(); ?> 希望能帮到您!

1
对我来说,我只使用 'dev' => '*.local' 就可以了。我还没有在团队环境中进行100%的测试,但我认为它应该可以工作(大胆的假设:)假设你在OSX上,并且获得默认的 Alexs-iMac.local 类似的主机名。
至于模拟环境,我不确定它是否真正受支持。虽然这是可行的,但总的来说,环境的整个目的是开发需要完全不同于生产,并且这两者互相排斥。具有切换一个物理环境的能力似乎与此目标相矛盾。

我当然承认那一点。你可以尝试看看 detectEnvironment 数组是否可以级联。先设置 prod,然后是 'dev' => '*' 或其他什么的。话虽如此,既然你已经接受了使用环境变量的答案,那我就悄悄离开吧 :) - alexrussell
什么是级联? - Simon Bengtsson
我并不是真的想说级联,更多的是后面的规则会覆盖前面的规则吗?就像我之前说的,如果你有 ['prod' => 'servername.com', 'dev' => '*'],那么它是否按预期工作,并在生产环境中正确地看到 prod,其他所有情况都是 dev,还是反过来呢?无论如何,值得深入研究。 - alexrussell
啊!那可能行得通。然而,将开发环境作为默认设置可能存在安全问题。 - Simon Bengtsson
是的,我想是这样。如果能够避免不断更改文件,以便其他人加入或使用新计算机,那将是很好的。不过,我很快会添加另一个答案,介绍我最终采取的方法,与被接受的答案非常接近。 - Simon Bengtsson
显示剩余2条评论

0
我不喜欢生产环境默认设置,所以我将除了 live 服务器外的所有东西都转到本地配置:
在 bootstrap/start.php 中:
$env = $app->detectEnvironment(function(){
    if (gethostname() !== 'live_server_hostname'){
        return 'local';
    } else {
        return 'production';
    }
});

0
我所做的是,创建目录app/config/local并使用代码。
$env = $app->detectEnvironment(function(){
    return $_SERVER['HTTP_HOST']=="localhost"?"local":"production";
});

适用于本地主机和在线环境。


这很容易被“黑客”攻击。您可以通过在主机文件中将localhost重定向到您的实际域来尝试自己。这将使您能够以“本地”模式运行您的实际网站,从而可能会看到所有的db配置和密码等信息。 - Simon Bengtsson
当我使用 CLI(Artisan)时,这会为我抛出一个错误,因为它无法访问 HTTP_HOST。 - Alias

0
你可以使用类似这样的代码:
$env = $app->detectEnvironment(function(){
    if($_SERVER['HTTP_HOST'] == 'youdomain_local')
    {
        return 'local';
    }elseif($_SERVER['HTTP_HOST'] == 'youdomain_team')
    {
        return 'team';
    }else{
        return 'production';
    }
});

问题在于HTTP_HOST很容易被欺骗。 - Simon Bengtsson

0
bootstrap/start.php 中定义这个:
$env = $app->detectEnvironment(function() use($app) {

    $enviromentsHosts = [
        'localhost',
        'local',
    ];

    if ($app->runningInConsole() || in_array($app['request']->getHost(), $enviromentsHosts)) {

        return 'local';

    } else {

        return 'production';
    }
});

我认为最好只使用 Laravel 4 的资源。


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