简体   繁体   English

PDO拒绝在多个数据库之间切换!

[英]PDO refuses to switch between multiple Databases!

Please I am very new to PDO, rather a novice at PHP as well. 请问,我对PDO还是陌生的,对PHP也是一个新手。 I am currently working on a project that involves connections to many databases: MySQL, MSSQL and Oracle. 我目前正在从事一个涉及到许多数据库的连接的项目:MySQL,MSSQL和Oracle。 So I am using the class below, with PDO, for my connection. 因此,我将下面的类与PDO一起用于连接。 The class code is below. 类代码如下。

class db {

 private static $objInstance; /* * Class Constructor - Create a new database connection if one doesn't exist * Set to private so no-one can create a new instance via ' = new DB();' */ private function __construct() {} /* * Like the constructor, we make __clone private so nobody can clone the instance */ private function __clone() {} /* * Returns DB instance or create initial connection * @param * @return $objInstance; */ public static function getDB($DBtype, $DBindex) { include('vars.inc.php'); if (!self::$objInstance){ $DBid = $DBindex - 1; switch ($DBtype){ case "mysql": self::$objInstance = new PDO("mysql:host=".$dbvars[$DBid][0].";dbname=".$dbvars[$DBid][1], $dbvars[$DBid][2], $dbvars[$DBid][3]); break; case "mssql": self::$objInstance = new PDO("odbc:Driver={SQL Server};Server=".$dbvars[$DBid][0].";Database=".$dbvars[$DBid][1], $dbvars[$DBid][2], $dbvars[$DBid][3]); break; case "oci"; self::$objInstance = new PDO("oci:dbname=//".$dbvars[$DBid][0].":".$dbvars[$DBid][4]."/".$dbvars[$DBid][1], $dbvars[$DBid][2], $dbvars[$DBid][3]); break; // Add other case(s) here if another RDBMS (Relational Database Management system) is used default: break; } self::$objInstance-> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } return self::$objInstance; } 

}

And here is the vars include file that is required by the class, I used an array cos I felt this way, new databases can be added easily to the vars file by a non-programmer over time. 这是该类所需的vars包含文件,我使用了这种感觉的数组cos,随着时间的推移,非程序员可以轻松地将新数据库添加到vars文件中。 Of course, here, I have changed the var file values. 当然,在这里,我更改了var文件的值。

define('DB_SERVER', 'localhost');
define('DB_NAME', 'db1name');
define('DB_USER', 'root');
define('DB_PASSWORD', 'rootpass');
define('DB_PORT', '');

define('DB2_SERVER', 'xxx.xxx.xx.xxx');
define('DB2_NAME', 'db2name');
define('DB2_USER', 'root2');
define('DB2_PASSWORD', 'rootpass2');
define('DB2_PORT', '');

define('DB3_SERVER', 'xx.xxx.xxx.xxx');
define('DB3_NAME', db3name');
define('DB3_USER', 'root3');
define('DB3_PASSWORD', 'rootpass3');
define('DB3_PORT', '');

define('DB4_SERVER', 'xxx.xx.xxx.xx');
define('DB4_NAME', 'oracledb');
define('DB4_USER', 'root4');
define('DB4_PASSWORD', 'rootpass4');
define('DB4_PORT', '1521');

$dbvars = array( array(DB_SERVER, DB_NAME , DB_USER, DB_PASSWORD, DB_PORT),
               array(DB2_SERVER, DB2_NAME , DB2_USER, DB2_PASSWORD, DB2_PORT),
               array(DB3_SERVER, DB3_NAME , DB3_USER, DB3_PASSWORD, DB3_PORT),
               array(DB4_SERVER, DB4_NAME , DB4_USER, DB4_PASSWORD, DB4_PORT)               
             );

Now the problem is that, whenever I have connected to one database and try to run my queries on another one, PDO keeps remembering the old database. 现在的问题是,每当我连接到一个数据库并尝试在另一个数据库上运行查询时,PDO都会记住旧数据库。 But if I independently run either query, everything is fine. 但是,如果我独立运行任一查询,一切都很好。 Can someone please help with this, or suggest a better method? 有人可以帮忙吗,或提出更好的方法? :( :(

Eg 例如

include('./includes/db.class.php'); try { $result = DB::getDB("mysql", 3)->query("SELECT myrow FROM mytable");

  foreach($result as $row){ print $row['myrow'].'<br />'; } }catch(PDOException $e){ echo $e->getMessage(); } echo "<br />Then<br /><hr /><br />"; try { $result = DB::getDB("mysql", 1)->query("SELECT yourrow FROM yourtable"); foreach($result as $row){ print $row['yourrow'].'<br />' ; } }catch(PDOException $e){ echo $e->getMessage(); } 

In this case, PDO will simply keep checking DATABASE db1name for TABLE yourtable rather than check DATABASE db3name. 在这种情况下,PDO将仅继续检查TABLE yourtable的DATABASE db1name,而不是检查DATABASE db3name。 So PDO will throw an error: 因此PDO会引发错误:
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'db1name.yourtable' doesn't exist SQLSTATE [42S02]:找不到基表或视图:1146表'db1name.yourtable'不存在

You have it setup as a singleton. 您将其设置为单例。 So your next call to Db::getDB returns the original instance. 因此,您对Db::getDB下一次调用将返回原始实例。 If you want to cache the instances for the duration of the script, change $objInstance to an array, and then instead of doing: 如果要在脚本期间缓存实例,请将$objInstance更改$objInstance数组,然后不要执行以下操作:

if (!self::$objInstance){

Do

$signature = $DBtype . $DBindex;
if (!isset(self::$objInstances[$signature])) {

Of course you'll need to change the assignment lines and the return line as well, but I think you get the idea... 当然,您还需要更改分配线和返回线,但是我想您知道了...

It appears that your getDB function will only connect once because of this line: 似乎由于以下原因,您的getDB函数只会连接一次:

if (!self::$objInstance){

So the first time you execute it, it will connect, but on all subsequent calls the logic is ignored. 因此,第一次执行它时,它将连接,但是在所有后续调用中,该逻辑将被忽略。

I suggest adding another property to your class that stores the current DBType and changing your conditional to: 我建议向您的类中添加另一个属性,以存储当前的DBType并将您的条件更改为:

if (!self::$objInstance || $DBtype != self::$dbtype){

You would have to set $dbtype inside each case of the switch statement. 您必须在switch语句的每种情况下都设置$ dbtype。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM