如何让CakePHP3通过Apache环境变量选择数据库连接

如何让CakePHP3通过Apache环境变量选择数据库连接,cakephp,deployment,environment,Cakephp,Deployment,Environment,我正在使用cakephp v3,希望在两个不同的环境中安装该应用程序,一个用于开发,另一个用于生产。两个安装都应该包含完全相同的文件(和文件内容),因此我可以使用“git”或“svn”轻松部署应用程序 如果两个环境托管在同一台机器上,我需要不同的数据库设置(以便开发环境使用自己的“测试”数据库)。我考虑在app.php中配置两个“数据源”,一个用于生产,另一个用于开发 但我如何在这两个来源之间切换 更具体地说:目前,我在开发环境的Apache配置中定义了以下环境变量: SetEnv CAKEPH

我正在使用cakephp v3,希望在两个不同的环境中安装该应用程序,一个用于开发,另一个用于生产。两个安装都应该包含完全相同的文件(和文件内容),因此我可以使用“git”或“svn”轻松部署应用程序

如果两个环境托管在同一台机器上,我需要不同的数据库设置(以便开发环境使用自己的“测试”数据库)。我考虑在
app.php
中配置两个“数据源”,一个用于生产,另一个用于开发

但我如何在这两个来源之间切换

更具体地说:目前,我在开发环境的Apache配置中定义了以下环境变量:

SetEnv CAKEPHP_DEBUG 1
然后我在
app.php
文件中更改了“debug”的定义,如下所示:

'debug' => (bool)getenv('CAKEPHP_DEBUG'),
这仅在开发计算机上启用调试模式。现在我还想以同样简单的方式切换数据库配置

(我已经找到了一些cakephp v2的解决方案,但是它们都很老了,我不确定在cakephp v3中最好的方法是什么。)

您可以在配置中定义任意数量的连接 文件您还可以在运行时使用定义其他连接 Cake\Datasource\ConnectionManager::config()

因此,我想您可以在
AppController
beforeFilter
中检查debug的值,并更改默认的数据库连接

AppController.php

if(Configure::read('debug') == 1)
{
    ConnectionManager::config('default', [
        'className' => 'Cake\Database\Connection',
        'driver' => 'Cake\Database\Driver\Mysql',
        'persistent' => false,
        'host' => 'dev_server',
        'username' => 'dev_username',
        'password' => 'dev_passwd',
        'database' => 'development',
        'encoding' => 'utf8',
        'timezone' => 'UTC',
        'cacheMetadata' => true,
    ]);
}
'Datasources' => [
    'default' => getenv('CAKEPHP_DEBUG')== 1 ? [ /* debug params */ ] : [ /* default params */]
    ...
]
'Datasources' => [
    'debug' => [ /* debug params */ ],
    'default' => [ /* default params */]
]
我认为可以在app.php中使用三元运算符执行类似的操作

app.php

if(Configure::read('debug') == 1)
{
    ConnectionManager::config('default', [
        'className' => 'Cake\Database\Connection',
        'driver' => 'Cake\Database\Driver\Mysql',
        'persistent' => false,
        'host' => 'dev_server',
        'username' => 'dev_username',
        'password' => 'dev_passwd',
        'database' => 'development',
        'encoding' => 'utf8',
        'timezone' => 'UTC',
        'cacheMetadata' => true,
    ]);
}
'Datasources' => [
    'default' => getenv('CAKEPHP_DEBUG')== 1 ? [ /* debug params */ ] : [ /* default params */]
    ...
]
'Datasources' => [
    'debug' => [ /* debug params */ ],
    'default' => [ /* default params */]
]
但不知何故,这似乎不是一种“干净”的方式

我认为更简洁的方法是在app.php中设置这两种配置,然后在appController中选择要使用的配置

app.php

if(Configure::read('debug') == 1)
{
    ConnectionManager::config('default', [
        'className' => 'Cake\Database\Connection',
        'driver' => 'Cake\Database\Driver\Mysql',
        'persistent' => false,
        'host' => 'dev_server',
        'username' => 'dev_username',
        'password' => 'dev_passwd',
        'database' => 'development',
        'encoding' => 'utf8',
        'timezone' => 'UTC',
        'cacheMetadata' => true,
    ]);
}
'Datasources' => [
    'default' => getenv('CAKEPHP_DEBUG')== 1 ? [ /* debug params */ ] : [ /* default params */]
    ...
]
'Datasources' => [
    'debug' => [ /* debug params */ ],
    'default' => [ /* default params */]
]
表格文件

public static function defaultConnectionName() {
    if(Configure::read('debug') == 1)
        return 'debug';
    return 'default';
}

看起来不错,谢谢!但是,我更喜欢将DB配置放在app.php而不是AppController.php中。谢谢您的更新!三元运算符工作得很好!使用“defaultConnectionName”的解决方案不起作用:如果我正确读取了文档,则必须在每个*表类中覆盖此方法,并且我不希望如此频繁地重复代码……我想您可以创建一个父表,并让所有其他表从中继承。但可能已经结束了,另一种方法是根据环境加载不同/额外的配置文件。与此类似的内容,例如:@ndm在这种情况下,配置文件应该是什么?如果我理解得很好,它应该重新定义/覆盖数据源数组,对吗?