2

私はPDOに非常に慣れていないので、PHPの初心者でもあります。私は現在、MySQL、MSSQL、Oracleなどの多くのデータベースへの接続を含むプロジェクトに取り組んでいます。そのため、接続にはPDOを使用して以下のクラスを使用しています。クラスコードは以下のとおりです。

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;      

}

}

これがクラスに必要なvarsインクルードファイルです。私はこのように感じた配列cosを使用しました。新しいデータベースは、プログラマーでなくても、時間の経過とともにvarsファイルに簡単に追加できます。もちろん、ここでは、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)、
               アレイ(DB2_SERVER、DB2_NAME、DB2_USER、DB2_PASSWORD、DB2_PORT)、
               アレイ(DB3_SERVER、DB3_NAME、DB3_USER、DB3_PASSWORD、DB3_PORT)、
               アレイ(DB4_SERVER、DB4_NAME、DB4_USER、DB4_PASSWORD、DB4_PORT)               
             );

問題は、あるデータベースに接続して別のデータベースでクエリを実行しようとすると、PDOが古いデータベースを記憶し続けることです。しかし、どちらかのクエリを個別に実行すれば、すべて問題ありません。誰かがこれを手伝ってくれるか、より良い方法を提案できますか?:(

例えば

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();
}

この場合、PDOは、DATABASE db3nameをチェックするのではなく、TABLEyourtableのDATABASEdb1nameをチェックし続けます。したがって、PDOはエラーをスローします
。SQLSTATE[42S02]:ベーステーブルまたはビューが見つかりません:1146テーブル'db1name.yourtable'が存在しません

4

2 に答える 2

3

シングルトンとして設定しました。したがって、次の呼び出しDb::getDBは元のインスタンスを返します。スクリプトの実行中にインスタンスをキャッシュする場合は$objInstance、配列に変更してから、次の操作を行う代わりに実行します。

if (!self::$objInstance){

行う

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

もちろん、割り当て行と戻り行も変更する必要がありますが、私はあなたがアイデアを得ると思います...

于 2010-08-19T18:09:47.803 に答える
2

getDB関数は、次の行のために1回だけ接続するようです。

if (!self::$objInstance){

したがって、最初に実行すると接続されますが、それ以降のすべての呼び出しではロジックは無視されます。

現在のDBTypeを格納する別のプロパティをクラスに追加し、条件を次のように変更することをお勧めします。

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

switchステートメントの各ケース内に$dbtypeを設定する必要があります。

于 2010-08-19T18:07:09.930 に答える