由于生产配置中缺少环境变量,Artisan 迁移在开发环境中失败

Posted

技术标签:

【中文标题】由于生产配置中缺少环境变量,Artisan 迁移在开发环境中失败【英文标题】:Artisan migrate fails in development environment because of missing environment variable in production config 【发布时间】:2015-05-07 01:01:36 【问题描述】:

我有两个数据库配置,一个用于生产,一个用于开发:

// app/config/database.php
'connections' => array(
    'mysql' => array(
        'driver'    => 'mysql',
        'host'      => $_SERVER['RDS_HOSTNAME'],
        'database'  => $_SERVER['RDS_DB_NAME'],
        'username'  => $_SERVER['RDS_USERNAME'],
        'password'  => $_SERVER['RDS_PASSWORD'],
        'charset'   => 'utf8',
        'collation' => 'utf8_unicode_ci',
        'prefix'    => '',
    )
)

// app/config/development/database.php
'connections' => array(
    'mysql' => array(
        'driver'    => 'mysql',
        'host'      => $_SERVER['MYSQL_PORT_3306_TCP_ADDR'],
        'database'  => $_SERVER['MYSQL_ENV_MYSQL_DATABASE'],
        'username'  => $_SERVER['MYSQL_ENV_MYSQL_USER'],
        'password'  => $_SERVER['MYSQL_ENV_MYSQL_PASSWORD'],
        'charset'   => 'utf8',
        'collation' => 'utf8_unicode_ci',
        'prefix'    => '',
    )
)

相关数据库环境变量存在(以MYSQL_开头的),运行迁移命令时:

php artisan migrate --env=development

以下异常被抛出:


    "error":
        "type":"ErrorException",
        "message":"Undefined index: RDS_HOSTNAME",
        "file":"/var/www/app/config/database.php",
        "line":50
    

当我什至不想使用生产配置时,为什么 Laravel 会关心我的生产配置中的环境变量是否不存在?我该如何解决这个问题?

【问题讨论】:

可能是因为它是由 Laravel 处理的 PHP 警告,它将警告视为错误。 App::environment();输出“发展”? 是的,但是当我指定开发环境时,为什么 Laravel 甚至会执行生产配置?有没有办法让 Laravel 忽略这样的警告? @Th3Alchemist 是的,将die(var_dump(App::environment())); 放在文件顶部会导致它打印development 你运行什么 Laravel 版本?你能检查你的/bootstrap/start.php(4.2)并检查你的主机名是否注册为开发环境吗? 【参考方案1】:

当您的 .env 文件中包含以下内容时,可能会发生此问题

DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=test_db
DB_USERNAME=root
DB_PASSWORD=

相反,你应该有

RDS_CONNECTION=mysql
RDS_HOSTNAME=localhost
RDS_PORT=3306
RDS_DB_NAME=test_db
RDS_USERNAME=root
RDS_PASSWORD=

区别在于键的名称。除此之外,this might be of interest 以防该问题与 bash 和 AWS 有关。

【讨论】:

【参考方案2】:

我的建议是改用环境变量,并确保环境之间的键匹配(我认为这是你最大的问题)。

// File: .env.development.php
return [
    'database_mysql_host' => '',
    'database_mysql_database' => '',
    'database_mysql_username' => '',
    'database_mysql_password' => '',
];

然后你可以删除你的两个配置文件并修改app/config/database.php:

'connections' => array(
    'mysql' => array(
        'driver'    => 'mysql',
        'host'      => $_ENV['database_mysql_host'],
        'database'  => $_ENV['database_mysql_database'],
        'username'  => $_ENV['database_mysql_username'],
        'password'  => $_ENV['database_mysql_password'],
        'charset'   => 'utf8',
        'collation' => 'utf8_unicode_ci',
        'prefix'    => '',
    )
)

我暂时假设您正在 vhost 或其他一些 apache 配置文件中的生产服务器上设置环境变量。更改您为生产环境选择的“特殊”键设置它们的位置,以匹配您在开发环境中使用的键:

SetEnv database_mysql_host your value for RDS_HOSTNAME
SetEnv database_mysql_database your value for RDS_DB_NAME
SetEnv database_mysql_username your value for RDS_USERNAME
SetEnv database_mysql_password your value for RDS_PASSWORD

【讨论】:

不幸的是,这不是一个选择。 Docker 自动设置开发变量,更改它们将是一个 PITA。 RDS 变量由 Amazon Web Services 设置。 另一种解决方案可能是确保两组环境配置键至少在两个环境中都可用(即使为空)

以上是关于由于生产配置中缺少环境变量,Artisan 迁移在开发环境中失败的主要内容,如果未能解决你的问题,请参考以下文章

无法通过 artisan 命令运行迁移

Laravel 环境变量(没有在方法中传递默认值)在 Artisan 命令文件中不起作用

Laravel php artisan 迁移空数据库上的错误

在docker python中缺少环境变量:3使用docker-compose

Laravel artisan 迁移多个数据库

Artisan Migrate 访问被拒绝