php PDO通过函数在脚本期间更改连接

时间:2014-02-13 10:49:17

标签: php mysql database pdo connection

我有一个应用程序必须使用多个数据库,出于客户端保护和归档的原因,使用核心管理 - 例如用户详细信息存储。我很感激需要从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错误。

为什么一个人工作而不是另一个因为他们看起来相同,我怎么能解决这个问题?

2 个答案:

答案 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