gustavohrm
(Gustavohenriquerm)
May 16, 2012, 2:26pm
1
Bom dia,
Estou enfrentando um problema, temos sistema de gerenciamento de conteúdo e estou querendo passar ele pra YII.
Mas, no caso eu teria multi bancos, no nosso servidor temos os dados do cliente (tabela abaixo) e queria configurar o ‘db’ do ‘config/main.php’
para pegar os dados de acesso de acordo com o id do cliente.
Alguma ideia de como fazer isso?
tabela_bancos
| id_banco | host | nome_banco | usuario | senha |
--------------------------------------------------------------------------
| 1 | 189.255.212.4 | banco_1 | root | 123456 |
| 2 | 72.11.12.89 | cliente | cliente_rs | x54ds7 |
'db'=>array(
'connectionString' => 'mysql:host=localhost;dbname=banco_1',
'emulatePrepare' => true,
'username' => 'root',
'password' => '123456',
'charset' => 'utf8',
),
Clayton23
(Cleintonto)
May 16, 2012, 3:36pm
2
É só adicionar as conexões no seu arquivo de configuração:
'db'=>array(
'connectionString' => 'mysql:host=localhost;dbname=banco_1',
'emulatePrepare' => true,
'username' => 'root',
'password' => '123456',
'charset' => 'utf8',
),
'db2'=>array(
'connectionString' => 'mysql:host=localhost;dbname=banco_2',
'emulatePrepare' => true,
'username' => 'cliente2',
'password' => '123456',
'charset' => 'utf8',
),
'db3'=>array(
'connectionString' => 'mysql:host=localhost;dbname=banco_3',
'emulatePrepare' => true,
'username' => 'cliente3',
'password' => '123456',
'charset' => 'utf8',
),
Para cada usuário é só chamar um banco que você quer:
$query = Yii::app()->db2->createCommand("SELECT FROM TABLE");
$query = Yii::app()->db3->createCommand("SELECT FROM TABLE2");
Já fiz algo parecido para um cliente, usei o module do yii para cada banco de dados. Assim ele separa em separar as views, controllers, models para cada banco.
Guia:
www.yiiframework.com/doc/guide/1.1/en/basics.module
gustavohrm
(Gustavohenriquerm)
May 16, 2012, 3:56pm
3
É só adicionar as conexões no seu arquivo de configuração:
'db'=>array(
'connectionString' => 'mysql:host=localhost;dbname=banco_1',
'emulatePrepare' => true,
'username' => 'root',
'password' => '123456',
'charset' => 'utf8',
),
'db2'=>array(
'connectionString' => 'mysql:host=localhost;dbname=banco_2',
'emulatePrepare' => true,
'username' => 'cliente2',
'password' => '123456',
'charset' => 'utf8',
),
'db3'=>array(
'connectionString' => 'mysql:host=localhost;dbname=banco_3',
'emulatePrepare' => true,
'username' => 'cliente3',
'password' => '123456',
'charset' => 'utf8',
),
Para cada usuário é só chamar um banco que você quer:
$query = Yii::app()->db2->createCommand("SELECT FROM TABLE");
$query = Yii::app()->db3->createCommand("SELECT FROM TABLE2");
Já fiz algo parecido para um cliente, usei o module do yii para cada banco de dados. Assim ele separa em separar as views, controllers, models para cada banco.
Guia:
www.yiiframework.com/doc/guide/1.1/en/basics.module
Clayton, a ideia é boa, mas tenho muitos clientes (+100), o arquivo vai ficar muito extenso mesmo!
A idéia é ter uma estrutura fixa para todos, exibindo para cada um dos clientes somente os módulos que ele alugou, então usar:
$query = Yii::app()->db2->createCommand("SELECT FROM TABLE");
$query = Yii::app()->db3->createCommand("SELECT FROM TABLE2");
Geraria o problema de repetição de código. Fugiria completamente da POO.
A ideia é:
1° -> o 'db' primeiro com os valores do meu banco,
2° -> confere se o usuário é válido,
3° -> pega os dados na tabela "tabela_bancos" (que passei acima)
4° -> usa os dados dessa tabela no 'db' para fazer alterações no banco do cliente.
Mas é no 4° passo que tá o problema. Como fazer isso?
Gustavo, analise a idéia abaixo e veja se ela te auxilia:
Após identificar o banco para o usuário modifique o componente ‘db’:
$db = 'bd';
$component=Yii::createComponent(array(
'class' => 'CDbConnection',
'connectionString' => "mysql:host=localhost;dbname=$db",
'emulatePrepare' => true,
'username' => '',
'password' => '',
'charset' => 'utf8',
));
Yii::app()->setComponent('db',$component);
FLw
:wq!
Clayton23
(Cleintonto)
May 16, 2012, 5:34pm
5
Acho a idéia do Thiago uma boa.
Aqui um exemplo de como pode ser feito. Coloque o código no seu components/controller.php
public function init() {
// Retorna os dados do usuário de acordo com o login
$dadosUsuario=cliente::model()->find('......'),
$banco = dadosUsuario->banco;
$usuario= dadosUsuario->usuario;
$senha = dadosUsuario->senha;
$configuracaoBanco = array(
'class'=>'CDbConnection',
'connectionString'=>'mysql:host=localhost;dbname=$banco',
'username'=> $usuario,
'password'=> $senha,
);
Yii::app()->setComponent('db',Yii::CreateComponent($configuracaoBanco);
}
Clayton, perfeito!
Estava fazendo os testes e não conseguia achar o lugar correto para colocar o código que postei, com a sua dica funcionou como previsto.
Gustavo, testa ae e diga se resolveu seu problema.
Vlw!
gustavohrm
(Gustavohenriquerm)
May 16, 2012, 7:25pm
7
Acho a idéia do Thiago uma boa.
Aqui um exemplo de como pode ser feito. Coloque o código no seu components/controller.php
public function init() {
// Retorna os dados do usuário de acordo com o login
$dadosUsuario=cliente::model()->find('......'),
$banco = dadosUsuario->banco;
$usuario= dadosUsuario->usuario;
$senha = dadosUsuario->senha;
$configuracaoBanco = array(
'class'=>'CDbConnection',
'connectionString'=>'mysql:host=localhost;dbname=$banco',
'username'=> $usuario,
'password'=> $senha,
);
Yii::app()->setComponent('db',Yii::CreateComponent($configuracaoBanco);
}
“Quase” funcionou assim!
O "components/controller.php" ficou assim:
public function init()
{
if(!Yii::app()->user->isGuest)
{
$cliente = Clientes::model()->findByPk(Yii::app()->user->id);
$configuracaoBanco = array(
'class' => 'CDbConnection',
'connectionString' => "mysql:host=".$cliente->host.";dbname=".$cliente->banco,
'emulatePrepare' => true,
'username' => $cliente->usuario,
'password' => $cliente->senha,
'charset' => 'utf8',
);
Yii::app()->setComponent('db',Yii::CreateComponent($configuracaoBanco));
}
}
Se eu der:
echo Yii::app()->db->connectionString."<br>";
echo Yii::app()->db->username."<br>";
echo Yii::app()->db->password."<br>";
Aparece certinho todos os dados, mas ainda está fazendo consulta no banco de dados local e não do banco do cliente
Existe alguma função de "reload" de componentes?
Gustavo, estranho! Trabalhei com 2 bd(s) aqui variando de acordo com o login.
Teste:
public function init() {
if (Yii::app()->user->name == 'demo')
$db = 'teste';
if (Yii::app()->user->name == 'admin')
$db = 'teste2';
if (isset($db)) {
$component = Yii::createComponent(array(
'class' => 'CDbConnection',
'connectionString' => "mysql:host=localhost;dbname=$db",
'emulatePrepare' => true,
'username' => 'teste',
'password' => 'teste',
'charset' => 'utf8',
));
Yii::app()->setComponent('db', $component);
}
}
Os 2 bd(s) no exemplo existem em minha estrutura…
Em cada tabela dos db(s) existe uma linha…
No controller do modelo:
public function actionView($id){
$model = $this->loadModel($id);
$model->nome = Yii::app()->user->name;
$model->save();
$this->render('view',array(
'model'=>$model,
));
}
Acessei como ‘admin’ e ‘demo’ e ambos valores foram atualizados para os respectivos bd(s)…
Carreguei um modelo e analisei a conexão:
echo $model->dbConnection;
O bd está variando de acordo com o login…
Flw!
gustavohrm
(Gustavohenriquerm)
May 16, 2012, 8:13pm
9
Gustavo, estranho! Trabalhei com 2 bd(s) aqui variando de acordo com o login.
Teste:
public function init() {
if (Yii::app()->user->name == 'demo')
$db = 'teste';
if (Yii::app()->user->name == 'admin')
$db = 'teste2';
if (isset($db)) {
$component = Yii::createComponent(array(
'class' => 'CDbConnection',
'connectionString' => "mysql:host=localhost;dbname=$db",
'emulatePrepare' => true,
'username' => 'teste',
'password' => 'teste',
'charset' => 'utf8',
));
Yii::app()->setComponent('db', $component);
}
}
Os 2 bd(s) no exemplo existem em minha estrutura…
Em cada tabela dos db(s) existe uma linha…
No controller do modelo:
public function actionView($id)
{
$model = $this->loadModel($id);
$model->nome = Yii::app()->user->name;
$model->save();
$this->render('view',array(
'model'=>$model,
));
}
Acessei como ‘admin’ e ‘demo’ e ambos valores foram atualizados para os respectivos bd(s)…
Carreguei um modelo e analisei a conexão:
echo $model->dbConnection;
O bd está variando de acordo com o login…
Flw!
Bom saber que dá certo, mas olha só o meu como tá ficando:
Com o seguinte código:
<?php
echo Yii::app()->db->connectionString."<br>";
echo Yii::app()->db->username."<br>";
echo Yii::app()->db->password."<br>";
?>
<?php
echo "<pre>";
print_r($model->dbConnection);
?>
Tenho essa saída:
mysql:host=xxx.xxx.xxx.xxx;dbname=banco2
usuario_teste
252536
CDbConnection Object
(
[connectionString] => mysql:host=localhost;dbname=banco1
[username] => root
[password] => 123456
[schemaCachingDuration] => 0
[schemaCachingExclude] => Array
(
)
Clayton23
(Cleintonto)
May 16, 2012, 10:43pm
10
O componente ‘db’ é a conexão do banco padrão do Yii. Ao invés de usá-la você mesmo pode fazer a conexão com o banco de acordo com o login do usuário.
$connection=new CDbConnection($dsn,$username,$password);
www.yiiframework.com/doc/api/1.1/CDbConnection#init-detail
Existe um forma tb que vc pode trabalhar com subdominio, fiz um sistema que trabalha desta forma.
Segue o Wiki:
http://www.yiiframework.com/wiki/200/sub-domains-with-different-databases-in-yii
Fica mais personalizado.
Falow