I've 3 copies of my code - on development workstation, a test server and a production server.
Accordingly, I have 3 separate DB configs in the database.php
file named dev, test & production.
I'm trying to figure out a way to switch the connection based on a value written to the Configure
class. The way I'm trying to accomplish this out is to require a file called instance.php
in the last line of bootstrap.php
.
require( APP . 'Config/instance.php' );
My instance.php
looks like:
<?php
// Configure instance type
Configure::write( 'InstanceType', 'Development' );
//Configure::write( 'InstanceType', 'Test' );
//Configure::write( 'InstanceType', 'Production' );
On the development workstation, the first line will be uncommented. Likewise on Test and Production the 2nd and 3rd lines will remain uncommented.
What I need is a method (perhaps in AppModel
) that'll get executed before any other Model loads and will set the correct DB config. using the following code:
// Set DB Config
switch( Configure::read( 'InstanceType' ) ) {
case 'Development':
//default:
$this->useDbConfig = 'default';
break;
case 'Test':
$this->useDbConfig = 'test';
break;
case 'Production':
$this->useDbConfig = 'production';
break;
}
OR (condensed version)
$this->useDbConfig = Configure::read( 'InstanceType' ) == 'Development' ? 'default' : strtolower( Configure::read( 'InstanceType' ) );
I tried to put this into a __construct()
method inside AppModel
but that started throwing a bunch of errors about missing arguments to __construct
.
The outcome is to have:
database.php
on the 3 platforms.How can I make this work?
Thank you.
You are on the right track. However, the code can't be placed in the construct for AppController.php
.
Instead, add it to class DATABASE_CONFIG
in /app/Config/database.php
:
public function __construct() {
// Set DB Config
switch( Configure::read( 'InstanceType' ) ) {
case 'Development':
//default:
//do nothing, as $this->default holds the right config
break;
case 'Test':
$this->default = $this->test;
break;
case 'Production':
$this->default = $this->production;
break;
}
}
Option 2: Symlinks
A different approach is to create 3 different versions of your database.php
file, each holding the right database config for each server, which you maintain with the rest of your code.
/app/Config/database-development.php
/app/Config/database-test.php
/app/Config/database-production.php
These three files are copied over to all of your servers when you update the repositories.
You then create a symbolic link on each server pointing to the right config file:
// Development Server
ln -s app/Config/database-development.php app/Config/database.php
// Test Server
ln -s app/Config/database-test.php app/Config/database.php
// Production Server
ln -s app/Config/database-production.php app/Config/database.php
Make sure this symlink is ignored in .gitignore
, so it won't be overwritten (default CakePHP behaviour).
You still have to maintain 3 different database config files, but you do it locally. You can also get rid of Config/instance.php
.