Come ti connetti a più database MySQL su una singola pagina web?


179

Ho informazioni distribuite su alcuni database e voglio mettere tutte le informazioni su una pagina web usando PHP. Mi chiedevo come posso collegarmi a più database su una singola pagina Web PHP.

So come collegarmi a un singolo database usando:

$dbh = mysql_connect($hostname, $username, $password) 
        or die("Unable to connect to MySQL");

Tuttavia, posso semplicemente usare più comandi "mysql_connect" per aprire gli altri database e come PHP può sapere da quale database desidero estrarre le informazioni se ho più database collegati.

Risposte:


335

Attenzione: le mysql_xx funzioni sono deprecate da php 5.5 e rimosse da php 7.0 (vedi http://php.net/manual/intro.mysql.php ), utilizzare le mysqli_xxfunzioni o vedere la risposta di seguito da @Troelskn


È possibile effettuare più chiamate a mysql_connect(), ma se i parametri sono gli stessi è necessario passare true per il $new_linkparametro ' ' (quarto), altrimenti viene riutilizzata la stessa connessione. Per esempio:

$dbh1 = mysql_connect($hostname, $username, $password); 
$dbh2 = mysql_connect($hostname, $username, $password, true); 

mysql_select_db('database1', $dbh1);
mysql_select_db('database2', $dbh2);

Quindi, per interrogare il database 1, passare il primo identificatore di collegamento:

mysql_query('select * from tablename', $dbh1);

e per il database 2 passare il secondo:

mysql_query('select * from tablename', $dbh2);

Se non si passa un identificatore di collegamento, viene utilizzata l'ultima connessione creata (in questo caso quella rappresentata da $dbh2) ad es .:

mysql_query('select * from tablename');

Altre opzioni

Se l'utente MySQL ha accesso a entrambi i database e si trovano sullo stesso host (ovvero entrambi i DB sono accessibili dalla stessa connessione) è possibile:

  • Tieni aperta una connessione e chiama mysql_select_db()per scambiarla, se necessario. Non sono sicuro che questa sia una soluzione pulita e potresti finire per interrogare il database sbagliato.
  • Specificare il nome del database quando si fa riferimento alle tabelle all'interno delle query (ad es SELECT * FROM database2.tablename.). Questo è probabilmente un dolore da implementare.

Leggi anche la risposta di troelskn perché è un approccio migliore se sei in grado di utilizzare DOP piuttosto che le estensioni precedenti.


2
+1 Questa soluzione ha funzionato per me. Dopo due giorni di debug perché i miei modelli WordPress personalizzati stavano perdendo l'accesso all'oggetto $ WP_Query dopo una chiamata alla seconda connessione al database ...
Eddie B,

è possibile impostare uno di essi come predefinito e doverlo aggiungere $dbh2per il secondo solo quando necessario? Dover cambiare tutte le domande per questo approccio al lavoro probabilmente richiederebbe giorni solo per trovarli tutti ...
ThomasK

@ThomasK, potresti avvolgere mysql_query in una funzione con un parametro predefinito, ad esempio, db_query($query,$db='db1')e quindi aggiornare in massa tutte le tue vecchie query a cui fa db_query($query)seguito l'aggiornamento personalizzato a quelle non predefinite adb_query($query,'db2')
joshuahedlund

Utilizzando il tuo metodo, quale connessione verrà utilizzata se definisco due connessioni ma non specifico quale connessione utilizzare nella query?
Peter,

1
@Peter: secondo php.net/manual/en/function.mysql-query.php :If the link identifier is not specified, the last link opened by mysql_connect() is assumed.
Tom Haigh,

97

Se usi PHP5 (E dovresti, dato che PHP4 è stato deprecato), dovresti usare DOP , poiché questo sta lentamente diventando il nuovo standard. Uno (molto) importante vantaggio del DOP è che supporta parametri associati, il che rende il codice molto più sicuro.

Ti connetteresti tramite PDO, in questo modo:

try {
  $db = new PDO('mysql:dbname=databasename;host=127.0.0.1', 'username', 'password');
} catch (PDOException $ex) {
  echo 'Connection failed: ' . $ex->getMessage();
}

(Ovviamente sostituisci nome database, nome utente e password sopra)

È quindi possibile eseguire una query sul database in questo modo:

$result = $db->query("select * from tablename");
foreach ($result as $row) {
  echo $row['foo'] . "\n";
}

Oppure, se hai variabili:

$stmt = $db->prepare("select * from tablename where id = :id");
$stmt->execute(array(':id' => 42));
$row = $stmt->fetch();

Se hai bisogno di più connessioni aperte contemporaneamente, puoi semplicemente creare più istanze di PDO:

try {
  $db1 = new PDO('mysql:dbname=databas1;host=127.0.0.1', 'username', 'password');
  $db2 = new PDO('mysql:dbname=databas2;host=127.0.0.1', 'username', 'password');
} catch (PDOException $ex) {
  echo 'Connection failed: ' . $ex->getMessage();
}

5
Perché questa risposta non è in alto ?! Questo è il modo corretto di procedere.
MP Aditya,

10
@aditya menon secondo me, il modo giusto di fare qualcosa spesso non è la risposta giusta alla domanda in corso. il Asker non stava usando DOP nella sua domanda, ma le funzioni mysql native di php, quindi credo che la risposta più adatta avrebbe seguito il codice asker.
Jonathan dos Santos,

2
@adityamenon sotto la cui autorità? Ricorda che l'utente ha sempre ragione ... DOP è il modo migliore, ma entrambi i modi sono il modo giusto per risolvere il problema degli utenti. Si prega di notare la differenza tra giusto e migliore. Sì ... sono annoiato, quindi ho dovuto fare una dichiarazione.
JustinKaz,

$ Db1 e $ db2 rappresentano più connessioni mysql? Se è così, non va bene. Esiste un modo per ospitare più database con una sola connessione?
datasn.io

@kavoir Perché lo vorresti? Se necessario, è possibile modificare il database sulla connessione corrente con use DATABASENAME, ma non vedo il punto?
troelskn,

9

Ho appena semplificato la mia vita:

CREATE VIEW another_table AS SELECT * FROM another_database.another_table;

spero sia utile ... evviva ...


1
Questa è la soluzione più semplice se non si hanno tabelle con lo stesso nome in entrambi i database. Lo fai una volta e poi non devi più preoccuparti di più database.
Erel Segal-Halevi,

@ ErelSegal-Halevi purché sia ​​necessario solo l'accesso in sola lettura ai dati dall'altro db, giusto?
Buttle Butkus,

6

Invece di mysql_connect usa mysqli_connect .

mysqli fornisce una funzionalità per connettere più database contemporaneamente.

$Db1 = new mysqli($hostname,$username,$password,$db_name1); 
// this is connection 1 for DB 1

$Db2 = new mysqli($hostname,$username,$password,$db_name2); 
// this is connection 2 for DB 2

1
$ hostname = 'Your DB_Hostname'; $ username = 'Your DB_Username'; $ password = 'Your DB_password'; $ db_name1 = 'Your DB_Name 1'; $ db_name2 = 'Your DB_Name 2';
Kaushik,

E 'semplicemente sbagliato che questo non avrebbe funzionato conmysql_connect
Nico Haase

4

Prova sotto il codice:

    $conn = mysql_connect("hostname","username","password");
    mysql_select_db("db1",$conn);
    mysql_select_db("db2",$conn);

    $query1 = "SELECT * FROM db1.table";
    $query2 = "SELECT * FROM db2.table";

È possibile recuperare i dati della query precedente da entrambi i database come di seguito

$rs = mysql_query($query1);
while($row = mysql_fetch_assoc($rs)) {
    $data1[] = $row;
}

$rs = mysql_query($query2);
while($row = mysql_fetch_assoc($rs)) {
    $data2[] = $row;
}

print_r($data1);
print_r($data2);

Le due query fornite funzionerebbero allo stesso modo senza chiamare mysql_select_dbnemmeno una volta - inoltre, chiamarlo due volte senza nient'altro nel mezzo è inutile
Nico Haase,

4
$dbh1 = mysql_connect($hostname, $username, $password);  
$dbh2 = mysql_connect($hostname, $username, $password, true); 

mysql_select_db('database1', $dbh1); 
mysql_select_db('database2',$dbh2); 

mysql_query('select * from tablename', $dbh1);
mysql_query('select * from tablename', $dbh2);

Questa è la soluzione più ovvia che uso ma ricordo, se il nome utente / la password per entrambi i database sono esattamente gli stessi nello stesso host, questa soluzione utilizzerà sempre la prima connessione. Quindi non essere confuso che in questo caso non funziona. Quello che devi fare è creare 2 utenti diversi per i 2 database e funzionerà.


3

A meno che non sia necessario avere in gioco più di un'istanza di un oggetto PDO, considerare quanto segue:

$con = new PDO('mysql:host=localhost', $username, $password, 
      array(PDO::ATTR_PERSISTENT => true));

Si noti l'assenza di dbname=argomenti di costruzione.

Quando ti colleghi a MySQL tramite un terminale o un altro strumento, il nome del database non è necessario. È possibile passare da un database all'altro usando l' USE dbnameistruzione tramite il PDO::exec()metodo

$con->exec("USE someDatabase");
$con->exec("USE anotherDatabase");

Ovviamente potresti voler racchiuderlo in una dichiarazione catch try.


Per coloro, che vorrebbero provare sopra approccio, dare un'occhiata prima di che stackoverflow.com/a/14933070/1623579
TheFrost

Adoro questa soluzione! Posso fare a meno dell'impostazione persistente, ma l'istanza di DOP è un'ottima soluzione. Si ottiene una connessione predefinita senza essere connessi a un database specifico.
Chuck Burgess,

2

Potresti essere in grado di utilizzare la sintassi di MySQLi, che ti consentirebbe di gestirla meglio.

Definire le connessioni al database, quindi ogni volta che si desidera eseguire una query su uno dei database, specificare la connessione corretta.

Per esempio:

$Db1 = new mysqli('$DB_HOST','USERNAME','PASSWORD'); // 1st database connection 
$Db2 = new mysqli('$DB_HOST','USERNAME','PASSWORD'); // 2nd database connection

Quindi per interrogarli sulla stessa pagina, utilizzare qualcosa del tipo:

$query = $Db1->query("select * from tablename")
$query2 = $Db2->query("select * from tablename")
die("$Db1->error");

Passare a MySQLi in questo modo ti aiuterà.


Migliora la tua sintassi (questo non è un sms) e formatta il tuo codice con gli strumenti (Ctrl + K, per esempio).
fedorqui "SO smettere di danneggiare" il

2

In realtà non hai bisogno select_db. È possibile inviare una query a due database contemporaneamente. Innanzitutto, concedi una sovvenzione DB1a cui scegliere DB2entro GRANT select ON DB2.* TO DB1@localhost;. Poi, FLUSH PRIVILEGES;. Infine, sei in grado di eseguire "query su più database" come SELECT DB1.TABLE1.id, DB2.TABLE1.username FROM DB1,DB2ecc. (Non dimenticare che hai bisogno dell'accesso "root" per utilizzare il comando grant)


1

se stai usando mysqli e hai due file db_connection. come il primo è

define('HOST','localhost');
define('USER','user');
define('PASS','passs');
define('**DB1**','database_name1');

$connMitra = new mysqli(HOST, USER, PASS, **DB1**);

il secondo è

    define('HOST','localhost');
    define('USER','user');
    define('PASS','passs');
    define(**'DB2**','database_name1');

    $connMitra = new mysqli(HOST, USER, PASS, **DB2**);

Quindi basta cambiare il nome del passaggio dei parametri in mysqli come DB1 e DB2. se si passa lo stesso parametro in mysqli supponiamo DB1 in entrambi i file, il secondo database non si collegherà più. Quindi ricorda che quando usi due o più connessioni, passa un nome di parametro diverso nella funzione mysqli


-1
<?php
    // Sapan Mohanty
    // Skype:sapan.mohannty
    //***********************************
    $oldData = mysql_connect('localhost', 'DBUSER', 'DBPASS');
    echo mysql_error();
    $NewData = mysql_connect('localhost', 'DBUSER', 'DBPASS');
    echo mysql_error();
    mysql_select_db('OLDDBNAME', $oldData );
    mysql_select_db('NEWDBNAME', $NewData );
    $getAllTablesName    = "SELECT table_name FROM information_schema.tables WHERE table_type = 'base table'";
    $getAllTablesNameExe = mysql_query($getAllTablesName);
    //echo mysql_error();
    while ($dataTableName = mysql_fetch_object($getAllTablesNameExe)) {

        $oldDataCount       = mysql_query('select count(*) as noOfRecord from ' . $dataTableName->table_name, $oldData);
        $oldDataCountResult = mysql_fetch_object($oldDataCount);


        $newDataCount       = mysql_query('select count(*) as noOfRecord from ' . $dataTableName->table_name, $NewData);
        $newDataCountResult = mysql_fetch_object($newDataCount);

        if ( $oldDataCountResult->noOfRecord != $newDataCountResult->noOfRecord ) {
            echo "<br/><b>" . $dataTableName->table_name . "</b>";
            echo " | Old: " . $oldDataCountResult->noOfRecord;
            echo " | New: " . $newDataCountResult->noOfRecord;

            if ($oldDataCountResult->noOfRecord < $newDataCountResult->noOfRecord) {
                echo " | <font color='green'>*</font>";

            } else {
                echo " | <font color='red'>*</font>";
            }

            echo "<br/>----------------------------------------";

        }     

    }
    ?>

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.