问题
I want to switch DB based on domain, selecting credentials from another DB, but I can't switch..
AppController.php
// Select username, password and database based on domain
$this->Company->find('first', [...]);
if ($company) {
// Connect to second database, droping connection from first.
$dataSource = ConnectionManager::getDataSource('default');
$dataSource->config['login'] = $company['Company']['dbuser'];
$dataSource->config['password'] = $company['Company']['dbpass'];
$dataSource->config['database'] = $company['Company']['dbname'];
/**
* PROBLEM START HERE:
* Here, need to use new database settings, and, this case
* Company table does not exists, but I always get it, so,
* I think I am connected with the first and not second connection.
*/
print_r($this->Company->find('first'));
}
How I can correct this?
EDIT
I have tried without success:
ConnectionManager::drop('default');
ConnectionManager::create('default', $settings);
A print_r(ConnectionManager::create('default', $settings))
return:
[... lots of things ... ]
[config] => Array
(
[persistent] =>
[host] => localhost
[login] => login
[password] => password
[database] => database
[port] => 3306
[datasource] => Database/Mysql
[prefix] =>
)
[... more things ... ]
EDIT 2
Now, I can switch database, but, Company Model always get the old database settings.
FooController.php
<?php
App::uses('AppController', 'Controller');
class FooController extends AppController {
var $uses = array('Foo', 'Company');
public function index() {
echo'<pre>';
print_r($this->Company->find('first')); // Here I get from old settings
print_r($this->Foo->find('first')); // Here I gete from new settings
echo'</pre>';
$this->layout = false;
$this->render(false);
}
}
AppController.php
public function beforeFilter() {
$company = ClassRegistry::init('Company')->find('first');
$settings = array(
'datasource' => 'Database/Mysql',
'persistent' => false,
'host' => 'localhost',
'login' => $company['Company']['dbuser'],
'password' => $company['Company']['dbpass'],
'database' => $company['Company']['dbname'],
'prefix' => ''
);
ConnectionManager::getDataSource('default')->disconnect();
ConnectionManager::drop('default');
ConnectionManager::create('default', $settings);
ConnectionManager::getDataSource('default')->connect();
}
回答1:
It looks like you need to dynamically create a config and change configs on-the-fly. I don't know if this will work, but it may lead you to the answer.
First we need to create a config for the datasource to use. For this we can use ConnectionManager::create
Next, we need to change configs on-the-fly and for that we can use Model::setDataSource
I haven't tried, but it looks like it should do. If there are issues, leave a comment so I can update the answer.
Edit: This may not work since every model would need to change the to the new datasource. There is a ConnectionManager::drop()
method that you could use to drop the default
config and then ConnectionManager::create('default', array(...));
to use a new default perhaps.
回答2:
You can switch databases in your database config file.
Configure your Config/database.php file as follows:
<?php
class DATABASE_CONFIG {
// config for e.g. localhost
public $default = array(
'datasource' => 'Database/Mysql',
'persistent' => false,
'host' => 'localhost',
'login' => 'root',
'password' => 'xxxxx',
'database' => 'cake',
'encoding' => 'utf8'
);
// DB config specifically for your domain
public $domain_x = array(
'datasource' => 'Database/Mysql',
'persistent' => false,
'host' => 'localhost',
'login' => 'username_at_hosting_provider',
'password' => '087bJ#ytvh&^YU#T',
'database' => 'blabla_cake',
'encoding' => 'utf8'
);
public function __construct(){
// switch config depending on domain / env('HTTP_HOST')
if(env('HTTP_HOST')=='domain_x.com'){
$this->default = $this->domain_x;
}
// otherwise keep $this->default
}
}
Edit:
It seems a was a bit too fast answering your question: it does not really cover your question. Sorry!
回答3:
Okay, so I managed to fix this problem creating the __construct
function whithin AppModel and put all the code to drop the default datasource and create another with the new config. Something like this:
AppModel.php
public function __construct($id = false, $table = null, $ds = null)
{
App::uses('CakeSession', 'Model/Datasource');
parent::__construct($id, $table, $ds);
if ($this->useDbConfig == 'default') {
// Change the datasource config
$user = CakeSession::read('Auth.User');
$this->changeDataSource($user);
}
}
public function changeDataSource($config)
{
...
...
...
$dados = array();
$dados['database'] = $config['titulo_bd'];
$dados['host'] = $config['host_bd'];
$dados['login'] = $config['login_bd'];
$dados['password'] = $config['senha_bd'];
$dados['datasource'] = 'Database/Mysql';
$dados['persistent'] = false;
$dados['prefix'] = '';
$dados['encoding'] = 'utf8';
ConnectionManager::create('default', $dados);
ConnectionManager::getDataSource('default')->connect();
}
回答4:
My case is very similar. In my case, I have two types of connections. One is the default core connection which uses the Config/database.php file for connection configurations. Second one is a dynamic configuration which uses db details saved for logged in user. So, for a few specific actions I have to switch between the default db connection and user based db connection. Here's how it came up.
To switch to user based db connection from default file
try {
ConnectionManager::getDataSource('default')->disconnect();
ConnectionManager::drop('default');
ConnectionManager::create('default', $this->config);
ConnectionManager::getDataSource('default')->connect();
$db = ConnectionManager::getDataSource('default');
} catch (MissingDatabaseException $e) {
$this->Session->setFlash($e->getMessage());
}
where $this->config is user based connection.
To switch back to default file based connection I do:
try {
ConnectionManager::getDataSource('default')->disconnect();
ConnectionManager::drop('default');
$dbconfig = new DATABASE_CONFIG();
ConnectionManager::create('default', $dbconfig->default);
ConnectionManager::getDataSource('default')->connect();
$db = ConnectionManager::getDataSource('default');
}
where $dbconfig->default i.e. $default contains my default connection configuration in Config/database.php
来源:https://stackoverflow.com/questions/11942189/cakephp-2-multiple-dbs