如何在CakePHP中为一个模型动态使用多个数据库

Ari*_*aan 16 php mysql cakephp model multiple-databases

好吧,我的第一个问题被修改了很多次,我选择删除它并重新构建我的问题.我已经创建了一个具有不同模型名称的小型测试用例项目,以便为我的问题找到合适的解决方案.

警告:不要将数据库混合

动机:我将用户数据分成多个数据库,以解决法律和性能问题.

目前我正在开发一个有多个的CakePHP项目,User每个项目User都有自己的数据库,有多个(cars就是其中一个).现在,我需要先解释一下:

每个User都有自己的数据库(不是表,数据库),所以数据库名称如下.

  • [DATABASE] app(这是应用程序的主数据库)
    • [表] users
    • [表] permissions(与此问题无关)
  • [DATABASE] app_user1(User.id1拥有整个数据库)
    • [TABLE] cars(完全归1 的User.id)
  • [DATABASE] app_user2(User.id2拥有整个数据库)
    • [表] cars(完全由2 拥有的User.id)
  • 等等...

我做了一个小图,它可以澄清数据库/表 -定义及其与模型的关系:

如何在CakePHP中为一个模型动态使用多个数据库

问题!!!

我不知道要连接哪个数据库,直到User登录.User及其数据库是动态创建的,所以我无法使用app/Config/database.php.

所以我现在正在编写一个扩展ModelConnectionManager类来绕过CakePHP的基本数据库行为.因此Car模型知道要使用哪个数据库.但我只是觉得这可以更轻松!

所以我想这一切归结为一个问题:

有没有更简单的方法来做到这一点?!

感谢任何愿意花时间和精力阅读和理解我的问题的人!

Ari*_*aan 38

这位先生(奥利维尔)有同样的问题!(一年前)Controllers 了一个小改编!这是非常小,事实证明,它工作在1.32.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;
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我在我的使用方式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);
  }

}
Run Code Online (Sandbox Code Playgroud)

我打赌,我不是第一个或最后一个有这个问题的人.所以我真的希望这些信息可以找到人和CakePHP社区.

  • +1 @"我打赌,我不是第一个或最后一个有这个问题的人.所以我真的希望这些信息会找到人和CakePHP社区." (2认同)
  • 非常感谢你...你的代码帮了我..我得到了'Strict(2048):只有变量应该通过引用分配[APP\Model\AppModel.php,第46行]`但是从中删除了**&****$ db =&ConnectionManager :: getDataSource($ datasource);**它工作得很好 (2认同)

小智 9

我不喜欢在代码中写下数据库的实际名称.对于多个数据库,您有database.php文件,您可以根据需要设置任意数量的数据库.

如果你想为一个特定的模式"切换"数据库在运行,使用的setDataSource方法.(见这里)

例如,如果您有两个数据库,则可以在database.php文件中将它们定义为"default"和"sandbox",作为示例.

然后,在您的代码中:

$this->Car->setDataSource('sandbox');
Run Code Online (Sandbox Code Playgroud)

沙箱是配置的名称,数据库的实际名称只在database.php文件中写入一次.