好吧,我的第一个问题是修改了很多次,我选择将其删除,并重新制定我的问题。 我做了不同的型号,名称的小测试案例的项目找到我的问题妥善解决。
警告 :不要将数据库与表混合起来
动机 :我分开用户数据转化为法律和性能问题的多个数据库 。
目前我的工作具有多个一CakePHP的项目User
的每个User
都有它自己的多个表 ( 数据库 cars
是一个表 )。 现在,我需要先解释一下:
每个User
都有自己的数据库 (不是表, 数据库 ),所以数据库名称如下。
- [数据库]
app
(这是应用程序的主数据库) - [表格]
users
- [表格]
permissions
( 对这个问题不相关 )
- [数据库]
app_user1
( User.id
1拥有此整个数据库 ) - [表格]
cars
(由完全拥有的表 User.id
1)
- [数据库]
app_user2
( User.id
2拥有此整个数据库 ) - [表格]
cars
(由完全拥有的表 User.id
2)
- 等等...
我做了一个小图画可能阐明数据库 / 表 -定义和他们的模特的关系:
问题!!!
我不知道要连接的数据库 ,直到User
登录时, User
的和他们的数据库是动态创建的,所以我不能使用app/Config/database.php
。
所以,我目前正在写的一个扩展Model
和ConnectionManager
类绕过CakePHP的基本数据库的行为。 因此, Car
模型,知道使用哪个数据库 。 但我一直可以这样做更容易的感觉!
所以我想这一切都归结为一个问题:
是否有这样做的一个简单的方法?
由于任何人将采取谁的阅读和理解我的问题的时间和精力!
这位先生 ( 奥利弗 )有同样的问题! (前一年), 他写了一个小的调整对于Controller
小号! 这是非常小,事实证明,它工作在1.3和2.x。
总之,这是我最终的解决方案,我把在app/Model/AppModel.php
:
class AppModel extends Model
{
/**
* Connects to specified database
*
* @param String name of different database to connect with.
* @param String name of existing datasource
* @return boolean true on success, false on failure
* @access public
*/
public function setDatabase($database, $datasource = 'default')
{
$nds = $datasource . '_' . $database;
$db = &ConnectionManager::getDataSource($datasource);
$db->setConfig(array(
'name' => $nds,
'database' => $database,
'persistent' => false
));
if ( $ds = ConnectionManager::create($nds, $db->config) ) {
$this->useDbConfig = $nds;
$this->cacheQueries = false;
return true;
}
return false;
}
}
这里是我如何使用它在我的app/Controller/CarsController.php
:
class CarsController extends AppController
{
public function index()
{
$this->Car->setDatabase('cake_sandbox_client3');
$cars = $this->Car->find('all');
$this->set('cars', $cars);
}
}
我打赌,我不是第一个或最后一个解决这个问题。 所以,我真的希望这个信息会发现人们与CakePHP的社区。
我不喜欢写下来的代码数据库的实际名称的想法。 对于多个数据库,你有database.php中文件,其中,因为你需要,你可以设置多个数据库。
如果你想在飞行一个特定的模式来“开关”一个数据库,使用的setDataSource方法。 (见这里 )
例如,如果你有两个数据库,你可以在database.php中文件作为“默认”和“沙箱”中定义它们,作为一个例子。
然后,在你的代码:
$this->Car->setDataSource('sandbox');
沙箱是配置的名称,以及数据库的实际名称是在database.php中文件写入一次。
您可以使用完整的符号在mysql中总是查询任何数据库。 F.ex:
SELECT * FROM my_schema_name.table_name;
蛋糕的方法:
$db = $this->getDataSource();
$query = array(
'fields' => array('*'),
'table' => 'my_schema_name.table_name'
);
$stmt = $db->buildStatement($query, $this);
$result = $db->execute($stmt);
在您为database.php
public $mongo = array(
'datasource' => 'Mongodb.MongodbSource',
'database' => 'database_name_mongo',
'host' => 'localhost',
'port' => 27017,
);
在你的控制器,你可以使用
$this->Organisation->setDataSource('mongo');
然后应用查询像
this->Organisation->find('all');
这是公认的答案的人。 这将防止错误,如果新的数据源已经存在:
public function setDatabase($database, $datasource = 'default')
{
$newDatasource = $datasource . '_' . $database;
try {
// return the new datasource if it's already existed
$db = ConnectionManager::getDataSource($newDatasource);
$this->useDbConfig = $newDatasource;
$this->cacheQueries = false;
return true;
} catch (Exception $e) {
// debug($e->getMessage());
}
$db = ConnectionManager::getDataSource($datasource);
$db->setConfig(array(
'name' => $newDatasource,
'database' => $database,
'persistent' => false
));
if ( $ds = ConnectionManager::create($newDatasource, $db->config) ) {
$this->useDbConfig = $newDatasource;
$this->cacheQueries = false;
return true;
}
return false;
}