2010-10-12 115 views
3

我试图实现的结果涉及到一个应用程序与一个数据库与最小的表存储有关系统上的用户数据的数据库,这个数据库将用于验证用户的登录信息,当他们登录到应用。我想要做的就是根据用户在主数据库中存储的详细信息,在用户登录后动态连接到另一个数据库。与Zend动态数据库连接

基本上我希望系统上的每个用户都拥有自己的数据库,在登录后连接到该数据库,并且能够使用常见的db模型类(因为每个用户的db将具有与其他用户的db相同的表)。

这可能吗?如果是这样,我将如何实现动态数据库连接(假设在验证其登录详细信息的操作中)。

任何帮助将不胜感激。

回答

1

最简单的答案不是建立第二个连接,而是在确定给定用户需要的名称之后更改默认模式。

例如,取二次分贝的名称为给定用户:

$db = Zend_Db::factory(...options...); 
$secondary_db = $db->query("SELECT secondary_db 
    FROM user_data WHERE user = ?", $userid) 
    ->fetchOne(); 

然后运行查询,以改变的模式。注意USE语句不支持作为一个事先准备好的声明,所以你必须使用驱动程序API来执行它:

$db->getConnection()->query("use $secondary_db"); 

现在,如果你引用一个表,而不必限定它的模式,你会得到的表实例辅助数据库。这包括通过Zend_Db适配器或Table类运行的任何查询等。

USE语句仅在辅助数据库与主数据库位于同一数据库实例中并且具有用户详细信息时才有效。此外,这也假设您不需要针对数据库重新验证用户身份,因为每个用户都具有不同的数据库级凭据。

+0

谢谢比尔,我有几个关于这个解决方案的问题(跟我一起,我不是专家)。 1.在调用父类的构造函数之前,将我的USE查询放置在一个抽象类的构造方法中,它将扩展Zend_Db_Table_Abstract,然后让我的所有模型扩展abtract类? – machinemessiah 2010-10-12 06:12:15

+0

2.当你说“但USE语句只适用于你的辅助数据库与你的主数据库驻留在具有用户详细信息的数据库实例相同的数据库实例”时,你能否澄清,我不完全确定你的意思,以及我是否会满足这个条件。 再次感谢! – machinemessiah 2010-10-12 06:14:56

+1

他意味着你将不得不使用相同的服务器实例/ dsn ...例如,所有的dbs将不得不从MySQL服务器在'mysql:// localhost'而不是'mysql:// mysql。 AUTH。本地'和'mysql:// mysql.userbase.local' – prodigitalson 2010-10-12 15:08:30

1

当然有可能。实现将取决于比你给出的更具体的要求,但我可能会做某种Db_Manager类。抽象了所有的细节,以保持动作短,SEET ......那么你可能只是有这样一个动作:

public function loginAction() 
{ 
    $request = $this->getRequest(); 
    $user = $request->getParam('username'); 
    $pass = $request->getParam('password'); 

    $auth = new My_Auth_Adapter($user, $pass); 
    $authResult = Zend_Auth::getInstance()->authenticate($auth); 

    if($authResult->isValid()){ 
     My_Db_Manager::connectForUser($authResult->getIdentity()); 
    } 
} 

这样,您就可以控制的数据库的所有排序实际使用并传播到您的经理级内的模型。如果出现这种情况,它还会为您提供一个简单的中心点,以便在一个请求周期内处理多个数据库的工作。