我有一个应用程序必须使用多个数据库,出于客户端保护和归档的原因,使用核心管理 - 例如用户详细信息存储。我很感激需要从mysql扩展中迁移(很快就会被弃用)并且我首先尝试了mysqli,但是无法摆脱持久连接,即使使用change_user函数,可能是因为使用了相同的用户/传递组合,所以交叉数据库连接是可能的。
我在迁移期间实现了许多存储过程以减少瓶颈。 MYSQL现在将SP分配给每个特定的数据库,因此在进行CALL时连接到正确的数据库非常重要。这意味着在查询中放入完整的database.table引用是不切实际的
所以我转向了PDO。
我创建了一个测试脚本:
$db_host="localhost";
$db_username='root';
$db_pass='';
$add='admin';
$db_name='host_base_name'.$add;
try{
$db= new PDO('mysql:host='.$db_host.';dbname='.$db_name,$db_username,$db_pass);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
$result= $db->query("SELECT firstname from centralusers WHERE usr_id='1'");
while($row=$result->fetch(PDO::FETCH_ASSOC)){echo $row['firstname']."<br>";}
}
catch(PDOException $e){echo $e->getMessage();}
$add='test';
$db_name='host_base_name_'.$add;
try{
$db= new PDO('mysql:host='.$db_host.';dbname='.$db_name,$db_username,$db_pass);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
$result= $db->query("SELECT stage_desc from action_stage WHERE stage_id='1'");
while($row=$result->fetch(PDO::FETCH_ASSOC)){echo $row['stage_desc']."<br>";}
}
catch(PDOException $e){echo $e->getMessage();}
这成功地转换了 - 我尝试了三个数据库,但没有显示经济的第三个。
但是,在开发代码中,我的脚本有一个'require'文件,其中包含一个处理连接的函数。它通过调用发送到表名的最后一部分(一个在mysql扩展中运行良好的进程。这是代码;
function db_connect($add) {
$db=NULL;
$db_host="localhost";
$db_username='root';
$db_pass='';
$db_name='host_base_name_'.$add;
try{
$db= new PDO('mysql:host='.$db_host.';dbname='.$db_name,$db_username,$db_pass);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
}
catch(PDOException $e){echo $e->getMessage();}
return $db;
}
第二次调用(更改数据库)后,我的下一个查询产生一个错误,表明找不到表 - 并将表引用的'host_base_name_'部分作为原始引用。我以为NULL调用会破坏实例。
如果我把$ db = NULL;在调用脚本中,就在函数之前,我得到一个“对非对象调用成员函数查询()”的Scream错误。
为什么一个人工作而不是另一个因为他们看起来相同,我怎么能解决这个问题?
答案 0 :(得分:0)
为每个数据库分别设置PDO
$db_host="localhost";
$db_username='root';
$db_pass='';
$add='admin';
$db_name1='host_base_name'.$add1;One database
$db_name2='host_base_name'.$add2;Other database
try{
//PDO for one database
$db1= new PDO('mysql:host='.$db_host.';dbname='.$db_name1,$db_username,$db_pass);
$db1->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
//PDO for other database
$db2= new PDO('mysql:host='.$db_host.';dbname='.$db_name1,$db_username,$db_pass);
$db2->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
答案 1 :(得分:0)
对于将来遇到这种情况的人,我发现我确实可以用类替换函数调用并创建到不同数据库的新连接。在此过程中,我发现通过将'localhost'替换为'127.0.0.1'来快速提高速度 - 将测试脚本的执行时间从0.0060秒降至0.0029,这在复杂脚本中非常重要。
所以这是我的类 - 因为它无论如何都包含在脚本的顶部,我把主要的连接参数放在include的头部,这样它们就可以在类中使用了。 $ db_name在脚本中被修改,因此它引用了正确的数据库。
$db_host='127.0.0.1';
$db_user='root';
$db_pass='';
$db_name='host_base_name';
class databaseConnect{
public function connect($db_host, $db_user,$db_pass,$db_name){
try{
$db= new PDO('mysql:host='.$db_host.';dbname='.$db_name,$db_user,$db_pass, array(PDO::ATTR_PERSISTENT=>false));
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
}
catch(PDOException $e){echo "Error: ".$e->getMessage()."<br />"; die(); }
return $db;
}
}
我获得了新的数据库连接实例(在本例中使用下面的代码为'host_base_nametest')当我必须切换数据库时,我将$ con替换为另一个变量,实质上是在连接中给予我完全灵活且可传输的数据库命名: / p>
$add='test'; // in production this comes from another variable
$db_inst=$db_name.$add; //builds the database name
$con=new databaseConnect; //calls the class
$db=$con->connect($db_host, $db_user,$db_pass,$db_inst); //gets the new instance