Comment vous connectez-vous à plusieurs bases de données MySQL sur une seule page Web?

179

J'ai des informations réparties sur quelques bases de données et je veux mettre toutes les informations sur une page Web en utilisant PHP. Je me demandais comment je pouvais me connecter à plusieurs bases de données sur une seule page Web PHP.

Je sais comment me connecter à une seule base de données en utilisant:

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

Cependant, puis-je simplement utiliser plusieurs commandes "mysql_connect" pour ouvrir les autres bases de données, et comment PHP saurait-il de quelle base de données je veux que les informations soient extraites si plusieurs bases de données sont connectées.

JoshFinnie
la source

Réponses:

335

Attention: les mysql_xx fonctions sont obsolètes depuis php 5.5 et supprimées depuis php 7.0 (voir http://php.net/manual/intro.mysql.php ), utilisez des mysqli_xxfonctions ou voyez la réponse ci-dessous de @Troelskn


Vous pouvez faire plusieurs appels à mysql_connect(), mais si les paramètres sont les mêmes, vous devez passer true pour le $new_linkparamètre ' ' (quatrième), sinon la même connexion est réutilisée. Par exemple:

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

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

Ensuite, pour interroger la base de données 1, passez le premier identifiant de lien:

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

et pour la base de données 2, passez la seconde:

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

Si vous ne passez pas d'identifiant de lien, la dernière connexion créée est utilisée (dans ce cas, celle représentée par $dbh2) par exemple:

mysql_query('select * from tablename');

Autres options

Si l'utilisateur MySQL a accès aux deux bases de données et qu'elles sont sur le même hôte (c'est-à-dire que les deux bases de données sont accessibles à partir de la même connexion), vous pouvez:

  • Gardez une connexion ouverte et appelez mysql_select_db()pour permuter si nécessaire. Je ne suis pas sûr que ce soit une solution propre et vous pourriez finir par interroger la mauvaise base de données.
  • Spécifiez le nom de la base de données lorsque vous référencez des tables dans vos requêtes (par exemple SELECT * FROM database2.tablename). Cela sera probablement difficile à mettre en œuvre.

Veuillez également lire la réponse de troelskn car c'est une meilleure approche si vous êtes capable d'utiliser PDO plutôt que les anciennes extensions.

Tom Haigh
la source
2
+1 Cette solution a fonctionné pour moi. Après deux jours de débogage, pourquoi mes modèles WordPress personnalisés perdaient l'accès à l'objet $ WP_Query après un appel à la deuxième connexion à la base de données ...
Eddie B
est-il possible de définir l'un d'entre eux comme étant celui par défaut, et de devoir simplement en ajouter $dbh2pour le second uniquement lorsque cela est nécessaire? Devoir modifier toutes les requêtes pour que cette approche fonctionne prendrait probablement des jours pour les trouver toutes ...
ThomasK
@ThomasK, vous pouvez envelopper mysql_query dans une fonction avec un paramètre par défaut, par exemple, db_query($query,$db='db1')puis mettre à jour en masse toutes vos anciennes requêtes pour db_query($query)suivre une mise à jour personnalisée de vos requêtes non par défaut àdb_query($query,'db2')
joshuahedlund
En utilisant votre méthode, quelle connexion sera utilisée si je définis deux connexions mais ne spécifie pas la connexion à utiliser lors de la requête?
Peter
1
@Peter: selon 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

Si vous utilisez PHP5 (et vous devriez, étant donné que PHP4 est obsolète), vous devriez utiliser PDO , car cela devient lentement le nouveau standard. Un avantage (très) important de PDO est qu'il prend en charge les paramètres liés, ce qui rend le code beaucoup plus sécurisé.

Vous vous connectez via PDO, comme ceci:

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

(Bien sûr, remplacez le nom de la base de données, le nom d'utilisateur et le mot de passe ci-dessus)

Vous pouvez ensuite interroger la base de données comme ceci:

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

Ou, si vous avez des variables:

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

Si vous avez besoin de plusieurs connexions ouvertes à la fois, vous pouvez simplement créer plusieurs instances de 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();
}
troelskn
la source
5
Pourquoi cette réponse n'est-elle pas au sommet?! C'est la bonne façon de procéder.
Aditya MP
10
@aditya menon, à mon avis, la bonne façon de faire quelque chose n'est souvent pas la bonne réponse à la question posée. le demandeur n'utilisait pas PDO dans sa question mais des fonctions mysql natives de php, donc je crois que la réponse la plus appropriée suivrait le code du demandeur.
Jonathan dos Santos
2
@adityamenon sous l'autorité de qui? Rappelez-vous que l'utilisateur a toujours raison ... PDO est le meilleur moyen, mais les deux sont la bonne façon de résoudre le problème des utilisateurs. Veuillez noter la différence entre le bien et le meilleur. Oui ... je m'ennuie donc j'ai dû faire une déclaration.
JustinKaz
$ Db1 et $ db2 représentent-ils plusieurs connexions mysql? Si c'est le cas, ce n'est pas bon. Existe-t-il un moyen d'héberger plusieurs bases de données avec une seule connexion?
datasn.io
@kavoir Pourquoi voudriez-vous cela? Si besoin est, vous pouvez modifier la base de données sur la connexion actuelle avec use DATABASENAME, mais je ne vois pas l'intérêt?
troelskn
9

Je viens de simplifier ma vie:

CREATE VIEW another_table AS SELECT * FROM another_database.another_table;

j'espère que c'est utile ... bravo ...

Ihsan Kusasi
la source
1
C'est la solution la plus simple si vous n'avez pas de tables portant le même nom dans les deux bases de données. Vous le faites une fois, et vous n'avez plus à vous soucier de plusieurs bases de données.
Erel Segal-Halevi
@ ErelSegal-Halevi tant que vous n'avez besoin que d'un accès en lecture seule aux données de l'autre base de données, non?
Buttle Butkus
6

Au lieu de mysql_connect, utilisez mysqli_connect .

mysqli fournit une fonctionnalité pour connecter plusieurs bases de données à la fois.

$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
kaushik
la source
1
$ hostname = 'Votre DB_Hostname'; $ username = 'Votre DB_Username'; $ password = 'Votre DB_password'; $ db_name1 = 'Votre DB_Name 1'; $ db_name2 = 'Votre DB_Name 2';
kaushik
C'est juste faux que cela ne fonctionnerait pas avecmysql_connect
Nico Haase
4

Essayez le code ci-dessous:

    $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";

Vous pouvez récupérer les données de la requête ci-dessus à partir des deux bases de données comme ci-dessous

$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);
Paks
la source
Les deux requêtes données fonctionneraient de la même manière sans appeler mysql_select_dbune seule fois - aussi, l'appeler deux fois sans rien d'autre au milieu est 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);

C'est la solution la plus évidente que j'utilise, mais rappelez-vous simplement que si le nom d'utilisateur / mot de passe pour les deux bases de données est exactement le même dans le même hôte, cette solution utilisera toujours la première connexion. Alors ne soyez pas confus que cela ne fonctionne pas dans un tel cas. Ce que vous devez faire est de créer 2 utilisateurs différents pour les 2 bases de données et cela fonctionnera.

Fellow paresseux
la source
3

À moins que vous n'ayez vraiment besoin d'avoir plus d'une instance d'un objet PDO en jeu, tenez compte de ce qui suit:

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

Remarquez l'absence de dbname=dans les arguments de construction.

Lorsque vous vous connectez à MySQL via un terminal ou un autre outil, le nom de la base de données n'est pas nécessaire dès le départ. Vous pouvez basculer entre les bases de données en utilisant l' USE dbnameinstruction via la PDO::exec()méthode.

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

Bien sûr, vous voudrez peut-être envelopper cela dans une instruction catch try.

Michael Ratcliffe
la source
Pour ceux qui essaieraient l'approche ci-dessus, jetez un coup d'œil avant que stackoverflow.com/a/14933070/1623579
TheFrost
J'adore cette solution! Je peux me passer du paramètre persistant, mais l'instanciation de PDO est une excellente solution. Vous obtenez une connexion par défaut sans être connecté à une base de données spécifique.
Chuck Burgess
2

Vous pourrez peut-être utiliser la syntaxe MySQLi, ce qui vous permettrait de mieux la gérer.

Définissez les connexions à la base de données, puis chaque fois que vous souhaitez interroger l'une des bases de données, spécifiez la bonne connexion.

Par exemple:

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

Ensuite, pour les interroger sur la même page, utilisez quelque chose comme:

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

Passer à MySQLi de cette manière vous aidera.

user3857891
la source
Veuillez améliorer votre syntaxe (ce n'est pas un sms) et formater votre code avec les outils (Ctrl + K, par exemple).
fedorqui 'SO arrêtez de nuire'
2

Vous n'en avez pas vraiment besoin select_db. Vous pouvez envoyer une requête à deux bases de données en même temps. Tout d'abord, accordez une subvention à DB1pour sélectionner DB2par GRANT select ON DB2.* TO DB1@localhost;. Ensuite, FLUSH PRIVILEGES;. Enfin, vous pouvez faire une `` requête sur plusieurs bases de données '' comme SELECT DB1.TABLE1.id, DB2.TABLE1.username FROM DB1,DB2etc. (n'oubliez pas que vous avez besoin d'un accès `` root '' pour utiliser la commande grant)

Nagibaba
la source
1

si vous utilisez mysqli et avez deux fichiers db_connection. comme le premier est

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

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

le deuxième est

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

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

Alors changez simplement le nom du paramètre pass dans mysqli comme DB1 et DB2. si vous passez le même paramètre dans mysqli, supposons que DB1 dans les deux fichiers, la deuxième base de données ne se connectera plus. Alors rappelez-vous que lorsque vous utilisez deux connexions ou plus, passez un nom de paramètre différent dans la fonction mysqli

Kamal Bunkar
la source
-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/>----------------------------------------";

        }     

    }
    ?>
Sapan Mohanty
la source
Pour plus de détails, vous pouvez visiter github.com/sapankumarmohanty/CountRecordsAtMigrationFinalSync
htngapi