我正在迁移 Laravel 框架,但我在数据库设置方面遇到了问题,
具体来说,我设置了我的环境,它们在 application.php 配置文件中运行良好,但是 database.php 配置文件似乎没有效果。
即使我的环境文件夹中有一个 database.php 配置文件,它也永远不会加载,我将一堆无效字符(键盘混搭)放入文件中以使 php 抛出错误,但它永远不会被命中。
Laravel 不支持基于环境的数据库设置吗?还是我做错了?
我正在迁移 Laravel 框架,但我在数据库设置方面遇到了问题,
具体来说,我设置了我的环境,它们在 application.php 配置文件中运行良好,但是 database.php 配置文件似乎没有效果。
即使我的环境文件夹中有一个 database.php 配置文件,它也永远不会加载,我将一堆无效字符(键盘混搭)放入文件中以使 php 抛出错误,但它永远不会被命中。
Laravel 不支持基于环境的数据库设置吗?还是我做错了?
您绝对可以按环境设置数据库设置(和任何其他配置设置)。
对于 Laravel 3(对于 Laravel 4 和 Laravel 5,请参见下文):
首先 - 你需要$environments
在你的定义paths.php
并将其设置为这样的:
$environments = array(
'development' => array('*.dev'),
'production' => array('*.com'),
);
Laravel 会自动寻找这个变量,如果设置了,将使用相关的配置。
通常,您有一个config
文件夹,其中包含诸如database.php
和auth.php
Laravel_Env
现在只需为您计划使用的每个文件夹(例如 Development)创建一个新文件夹。你最终会得到这样的文件夹结构;
/application
/config
/development
database.php
/production
database.php
application.php
config.php
database.php
...
user_agents.php
你会注意到我只包含database.php
在每个子文件夹中。Laravel 将始终首先加载默认配置设置,然后使用环境设置中的任何自定义配置覆盖它们。
最后,在你的开发/数据库文件中,你会有这样的东西;
<?php
return array(
'default' => 'mysql'
);
ps 我刚刚在 Laravel 的当前 3.2.12 版本上测试了这个——它确实有效。
额外提示:您还可以为 Artisan 自动设置环境,因此您不必在每个命令行中手动包含环境!去做这个:
您需要知道运行 Artisan 的“主机名”。要找出答案 - 暂时artisan.php
在您的根文件夹中编辑,并添加var_dump(gethostname());
到第 2 行(即在所有内容之上)。
php artisan
从命令行运行。您将获得一个带有您的主机名的字符串转储。就我而言,它是“TSE-Win7”;
删除对artisan.php
文件的更改
将您的主机名(即“TSE-Win7”)添加到环境中。
你应该得到这样的结果:
$environments = array(
'development' => array('*.dev', 'TSE-Win7'),
'production' => array('*.com'),
);
Artisan 现在将使用您的开发环境运行。如果您部署到实时服务器 - 重新运行这些步骤以获取服务器的主机名(),您可以仅为服务器配置特定的工匠配置!
对于 Laravel 4:
默认环境始终为production
. 但是在您的start.php文件中,您可以定义其他环境。
$env = $app->detectEnvironment(array(
'local' => array('your-machine-name'),
));
在 Linux 和 Mac 上,您可以在终端中确定您hostname
的类型hostname
- 它会输出您的计算机名称。在 Windowsdd(gethostname());
上,放在文件的开头routes.php
- 并运行网站一次 - 它会显示您计算机的当前主机名。
要将当前环境作为应用程序中的变量- 请在此处阅读此 SO 答案。Laravel 4:如何获取环境值?
对于 Laravel 5:
有一个配置文件,.env
在您的根目录中调用。
观看此 laracast,配置充分解释。
如果您使用的是工匠(laravel 的命令行),则需要添加的每个命令
artisan bla bla bla --env=Development
或者
artisan bla bla bla --env=Production
下面是我如何根据需要设置它。
我个人需要 4 种不同的配置:
由于我的所有 4 个环境都有不同的目录结构,我可以使用 php 的魔术常量__DIR__来获取应用程序目录,然后使用strpos()函数进行简单检查并返回适当的环境。它还将处理 Artisan 环境,无需手动输入环境或添加任何机器名称。
在 - 的里面
引导程序/start.php
添加回调函数
$env = $app->detectEnvironment(function(){
$haystack = __DIR__; // Catch the directory path
// Set the booleans (remove the first '/', else strpos() will return 0)
$isLocal = strpos($haystack, 'Library/WebServer/Documents/www/my-domain.com/development/');
$isDevelopment = strpos($haystack, 'var/www/my-domain.com/development/');
$isTest = strpos($haystack, 'var/www/my-domain.com/test/');
$isProduction = strpos($haystack, 'var/www/my-domain.com/web/');
// Set the environments
if ($isLocal) $environment = "local";
if ($isDevelopment) $environment = "development";
if ($isTest) $environment = "test";
if ($isProduction) $environment = "production";
// Return the appropriate environment
return $environment
});
我们还可以一次将所有值设置并抓取到一个数组中,然后运行一个 foreach 循环。
提示:由于我们使用strpos()函数,该函数根据$haystack检查给定值第一次出现的位置,并返回位置编号。我们实际上不必提供整个路径,我们可以简单地从每条路径中添加一个独特的值来完成工作。
// Check the boolean, if true set to given value, else set NULL
$environments[] = strpos($haystack, "Library") ? 'local' : NULL;
$environments[] = strpos($haystack, "develop") ? 'development': NULL;
$environments[] = strpos($haystack, "test") ? 'test' : NULL;
$environments[] = strpos($haystack, "web") ? 'production' : NULL;
// Loop through each, if not null then we have our environment
foreach ($environments as $environment) {
if(!is_null($environment))
return $environment;
}
无论我们是在一台机器还是多台机器上工作,通过相同路径到达不同环境的可能性非常小。
或者我认为。:)
使用Laravel 文档中详述的DotEnv方法。
我们正在使用本Laracasts 课程中推荐的方法 Jeffrey Way 。
为每个环境创建config
目录。
/app
/config
/local
database.php
/production
database.php
在生产服务器上设置环境变量。谷歌为您的生产平台上的最佳方法。例如,这里是对Ubuntu、Dreamhost和Heroku的很好的建议。我们添加了一行/etc/environment
:
ENV=production
将此闭包添加到/bootstrap/start.php
. 使用此设置,任何缺少ENV
环境变量的服务器都将默认为local
环境配置。
$env = $app->detectEnvironment(
function () {
return getenv('ENV') ? : 'local';
}
);
如何设置环境特定的配置现在在官方 Laravel 文档中。我建议使用他们的方法而不是接受的答案:
根据应用程序运行的环境设置不同的配置值通常很有帮助。例如,您可能希望在本地开发机器上使用与生产服务器上不同的缓存驱动程序。使用基于环境的配置很容易做到这一点。
只需在 config 目录中创建一个与您的环境名称匹配的文件夹,例如 local。接下来,创建您希望覆盖的配置文件并指定该环境的选项。例如,要覆盖本地环境的缓存驱动程序,您可以在 app/config/local 中创建一个 cache.php 文件,其内容如下:
<?php
return array(
'driver' => 'file',
);
注意:不要使用“测试”作为环境名称。这是为单元测试保留的。请注意,您不必指定基本配置文件中的每个选项,而只需指定您希望覆盖的选项。环境配置文件将“级联”在基础文件之上。
接下来,我们需要指示框架如何确定它在哪个环境中运行。默认环境始终是生产环境。但是,您可以在安装根目录的 bootstrap/start.php 文件中设置其他环境。在此文件中,您将找到一个 $app->detectEnvironment 调用。传递给此方法的数组用于确定当前环境。您可以根据需要将其他环境和机器名称添加到阵列中。
<?php
$env = $app->detectEnvironment(array(
'local' => array('your-machine-name'),
));
在此示例中,“local”是环境名称,“your-machine-name”是服务器的主机名。在 Linux 和 Mac 上,您可以使用 hostname 终端命令确定您的主机名。
如果您需要更灵活的环境检测,您可以将 Closure 传递给 detectEnvironment 方法,让您可以随心所欲地实现环境检测:
$env = $app->detectEnvironment(function()
{
$domain = explode('.', $_SERVER['HTTP_HOST']);
switch($domain[0])
{
case 'localhost':
case 'localhost:8080':
case 'dev':
return 'development';
break;
case 'mysite':
default:
return 'production';
break;
}
});
您可以通过 environment 方法访问当前的应用程序环境:
访问当前应用环境
$environment = App::environment();
您还可以将参数传递给 environment 方法以检查环境是否与给定值匹配:
if (App::environment('local'))
{
// The environment is local
}
if (App::environment('local', 'staging'))
{
// The environment is either local OR staging...
}
我今天一直在努力解决这个问题,努力找出如何最好地为数据库进行环境设置。最后,在尝试了几种方法之后,我完全同意@troy-harvey 的观点,即 Jeffrey Way 的建议是最好的(至少对我来说)。我要补充的一件事是(如果我错了,请纠正我),您需要通过相应的环境设置文件访问您试图在环境设置文件中覆盖的设置数组键。我开始返回一个简单的数组:
return [
'database' => '<db_name>',
'username' => '<db_user>',
'password' => '<db_pass>',
];
在一个app/config/staging/database.php
. 这没有任何效果,并且在头疼之后意识到您需要访问数组,因为它显示在 中app/config/database.php
,如下所示:
<?php
return [
'connections' => [
'mysql' => [
'database' => '<db_name>',
'username' => '<db_user>',
'password' => '<db_pass>'
]
]
];
至少这就是我最终设法获得我的设置的方式。
在这里添加这个,以防其他人正在努力解决这个问题。当我意识到我犯了一个多么明显的错误时,我明白了。
2014 年 7 月 1 日编辑
对此的补充说明是,从 4.1 开始,Laravel 附带了一个 append_config() 辅助函数,用于将环境配置附加到主配置数组。
对于上面给出的示例,这看起来像这样:
<?php
return append_config([
'connections' => [
'mysql' => [
'database' => '<db_name>',
'username' => '<db_user>',
'password' => '<db_pass>'
]
]
]);
如果您尝试在 Windows 环境中使用 Laravel,请查看 Laravel 项目顶级文件夹中文件 .env 中的设置 - 这些将覆盖您在 config/database.php 中的任何数据库设置
在 Laravel 3 中检测环境是:
Request:env()
这将返回在 paths.php 文件中找到的环境数组中标识的任何内容。
正如之前在 Laravel 4 中提到的,现在是:
App:: environment()
我的做法!
$env = $app->detectEnvironment( function() {
if ( file_exists('../.env.local.php') ) {
return 'local';
}
if ( file_exists('../.env.beta.php') ) {
return 'beta';
}
return 'production';
} );
如果你在 Laravel 4 上,这里有一个要点,它将带你一步一步地完成整个过程。感谢@“The Shift Exchange”的回答,指导我创建它。