Laravel种子特定环境

时间:2014-03-27 16:01:37

标签: laravel-4 environment-variables

我们正在开发基于Laravel 4的多个应用程序。这些应用程序在同一个Web服务器上运行。

Laravel4环境检测基于主机名,因为我们在同一台计算机上有多个应用程序。 我们在检测区域中创建了一个变通方法,以便根据网址设置环境。

我们在更新应用程序数据库时运行artisan --env=my_env migrate命令。问题在于播种,播种命令没有env选项,因此它会尝试根据主机名对数据库进行播种,这将不正确。

我正在努力寻找解决方案,但我在互联网上找不到任何解决方案,而我建立新命令的尝试只是耗费了太多时间和精力。

有人知道如何在播种时设置环境吗?

PS:我通过Grunt在服务器上运行命令,我知道环境 - 将它注入命令 - 。

2 个答案:

答案 0 :(得分:2)

你指出它非常好,Laravel环境猜测糟透了我们使用它的方式,但你可以改变它:

这就是我如何完美地设置我的环境,所以我不必处理主机名,但仍然没有让我的本地环境与分期和制作发生冲突。

在应用程序的根目录中创建一个.environment文件,并定义您的环境并将敏感信息添加到其中:

<?php

return array(

     'APPLICATION_ENV' => 'development', /// this is where you will set your environment

     'DB_HOST' => 'localhost',
     'DB_DATABASE_NAME' => 'laraveldatabase',
     'DB_DATABASE_USER' => 'laraveluser',
     'DB_DATABASE_PASSWORD' => '!Bassw0rT',

);

将其添加到您的.gitignore文件中,这样您就不会有将密码发送到Github或任何其他服务器的风险。

$app->detectEnvironment之前,在文件bootstrap/start.php中,将您的.environment文件加载到PHP环境中:

foreach(require __DIR__.'/../.environment' as $key => $value) 
{
    putenv(sprintf('%s=%s', $key, $value));
}

然后你必须使用它:

$env = $app->detectEnvironment(function () {

    return getenv('APPLICATION_ENV'); // your environment name is in that file!

});

它可以在任何地方使用,因此您不再需要为开发和生产分别设置目录:

<?php

return array(

    'connections' => array(

         'postgresql' => array(
              'driver'   => 'pgsql',
              'host'     => getenv('DB_HOST'),
              'database' => getenv('DB_DATABASE_NAME'),
              'username' => getenv('DB_DATABASE_USER'),
              'password' => getenv('DB_DATABASE_PASSWORD'),
              'charset'  => 'utf8',
              'prefix'   => '',
              'schema'   => 'public',
         ),

    ),

);

请注意,我没有设置后备:

return getenv('APPLICATION_ENV') ?: 'local';

因为我希望它在我部署应用程序的每台服务器上失败,所以永远不要忘记在其上配置我的环境。

然后您只需在DatabaseSeeder类中选择环境:

public function run()
{
    if( App::environment() === 'development' )
    {
        $this->call('UserTableSeeder');
    } 
}

答案 1 :(得分:1)

有些日子我想到了这种情况,并得出结论,我们正在尝试做的事情并不正确。

正确的方法是每个应用程序都有自己的配置文件 - 具有不同的envs-。这样Laravel的解析功能就可以了。 现在的情况是,我们在一个应用程序中有多个客户端,而strore在一个应用程序中执行-clients-配置文件。在这种情况下,主机名解析将返回一个客户端 - 每次相同的客户端配置都是因为客户端应用程序在同一台机器上运行。

我们的解决方案 我们将为不同的客户端编写一个部署脚本,以便每个客户端都有自己的应用程序及其配置(复制应用程序,复制/覆盖客户端配置到应用程序)。

<强>变通 @Antonio Carlos Ribeiro的答案是在外面工作,但对我们的应用程序有很大的影响。我们使用不同的环境,使用此解决方案,我们必须在所有环境中使用相同的用户/通行证信息,或者提供不同的.environment文件。

我写了一个Artisan命令,暂时让我们的部署工作。此命令可以使用提供的环境(php artisan db:seed_env my_env)的配置为数据库设定种子。

use Illuminate\Console\Command;
use Illuminate\Config\Repository;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;

class SeedEnvironmentDb extends Command {

    /**
     * The console command name.
     *
     * @var string
     */
    protected $name = 'db:seed_env';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Seed a database with the configuration of the environment';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function fire()
    {
        $cmd = $this;
        $app = App::make('app');

        // force the environment to the given one.
        $env = $app->detectEnvironment(function() use ($cmd) {
            return $cmd->argument('environment');
        });

        // create new config with the correct environment and overwrite the current one.
        $app->instance('config', $config = new Repository(
            $app->getConfigLoader(), $env
        ));

        // trigger the db seed (now with the correct environment)
        $this->call('db:seed');
    }

    /**
     * Get the console command arguments.
     *
     * @return array
     */
    protected function getArguments()
    {
        return array(
            array('environment', InputArgument::REQUIRED, 'The environment to seed.'),
        );
    }

    /**
     * Get the console command options.
     *
     * @return array
     */
    protected function getOptions()
    {
        return array();
    }

}