¿Cómo se conecta a múltiples bases de datos MySQL en una sola página web?

179

Tengo información dispersa en algunas bases de datos y quiero poner toda la información en una página web usando PHP. Me preguntaba cómo puedo conectarme a múltiples bases de datos en una sola página web PHP.

Sé cómo conectarme a una sola base de datos usando:

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

Sin embargo, ¿puedo usar varios comandos "mysql_connect" para abrir las otras bases de datos y cómo PHP sabría de qué base de datos quiero obtener la información si tengo varias bases de datos conectadas?

JoshFinnie
fuente

Respuestas:

335

Advertencia: las mysql_xx funciones están en desuso desde php 5.5 y se eliminan desde php 7.0 (consulte http://php.net/manual/intro.mysql.php ), use mysqli_xxfunciones o vea la respuesta a continuación de @Troelskn


Puede realizar varias llamadas a mysql_connect(), pero si los parámetros son los mismos, debe pasar true para el '$new_link parámetro ' (cuarto), de lo contrario, se reutilizará la misma conexión. Por ejemplo:

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

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

Luego, para consultar la base de datos 1, pase el primer identificador de enlace:

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

y para la base de datos 2 pase el segundo:

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

Si no pasa un identificador de enlace, se utiliza la última conexión creada (en este caso, la representada por $dbh2 ), ejemplo:

mysql_query('select * from tablename');

Otras opciones

Si el usuario de MySQL tiene acceso a ambas bases de datos y están en el mismo host (es decir, se puede acceder a ambos DB desde la misma conexión), usted podría:

  • Mantenga una conexión abierta y llame mysql_select_db() para intercambiar según sea necesario. No estoy seguro de que esta sea una solución limpia y podría terminar consultando la base de datos incorrecta.
  • Especifique el nombre de la base de datos cuando haga referencia a tablas dentro de sus consultas (por ejemplo SELECT * FROM database2.tablename). Es probable que esto sea difícil de implementar.

También lea la respuesta de troelskn porque es un mejor enfoque si puede usar PDO en lugar de las extensiones más antiguas.

Tom Haigh
fuente
2
+1 Esta solución funcionó para mí. Después de dos días de depuración, por qué mis plantillas personalizadas de WordPress estaban perdiendo acceso al objeto $ WP_Query después de una llamada a la segunda conexión de la base de datos ...
Eddie B
¿es posible configurar uno de ellos como el predeterminado y solo tener que agregar $dbh2para el segundo solo cuando sea necesario? Tener que cambiar todas las consultas para que este enfoque funcione probablemente lleve días encontrarlas todas ...
ThomasK
@ThomasK, podría ajustar mysql_query en una función con un parámetro predeterminado, digamos, db_query($query,$db='db1')y luego actualizar en masa todas sus consultas anteriores para db_query($query)luego actualizarlas de manera personalizada a lasdb_query($query,'db2')
joshuahedlund
Usando su método, ¿qué conexión se usará si defino dos conexiones pero no especifico qué conexión usar en la consulta?
Peter
1
@ Peter: de acuerdo con 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 usa PHP5 (y debería, dado que PHP4 ha quedado en desuso), debe usar PDO , ya que esto se está convirtiendo lentamente en el nuevo estándar. Un beneficio (muy) importante de PDO es que admite parámetros enlazados, lo que hace que el código sea mucho más seguro.

Te conectarías a través de PDO, así:

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

(Por supuesto, reemplace databasename, nombre de usuario y contraseña arriba)

Luego puede consultar la base de datos de esta manera:

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

O, si tiene variables:

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

Si necesita múltiples conexiones abiertas a la vez, simplemente puede crear múltiples instancias 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
fuente
55
¿Por qué esta respuesta no está en la parte superior? Esta es la forma correcta de hacerlo.
Aditya MP
10
@aditya menon en mi opinión, la forma correcta de hacer algo a menudo no es la respuesta correcta a la pregunta en cuestión. el Asker no estaba usando PDO en su pregunta, sino funciones mysql nativas de php, por lo que creo que la respuesta más adecuada seguiría el código de Asker.
Jonathan dos Santos
2
@adityamenon bajo cuya autoridad? Recuerde que el usuario siempre tiene razón ... PDO es la mejor manera, pero ambas formas son la forma correcta de resolver el problema de los usuarios. Tenga en cuenta la diferencia entre lo correcto y lo mejor. Sí ... estoy aburrido, así que tuve que hacer una declaración.
JustinKaz
¿$ Db1 y $ db2 representan múltiples conexiones mysql? Si es así, eso no es bueno. ¿Hay alguna manera de acomodar múltiples bases de datos con una sola conexión?
datasn.io
@kavoir ¿Por qué quieres eso? Si es necesario, podría cambiar la base de datos en la conexión actual use DATABASENAME, pero no veo el punto.
troelskn
9

Acabo de hacer mi vida simple:

CREATE VIEW another_table AS SELECT * FROM another_database.another_table;

Espero que sea útil ... saludos ...

Ihsan Kusasi
fuente
1
Esta es la solución más fácil si no tiene tablas con el mismo nombre en ambas bases de datos. Lo hace una vez, y luego ya no tiene que preocuparse por múltiples bases de datos.
Erel Segal-Halevi
@ ErelSegal-Halevi siempre que solo necesite acceso de solo lectura a los datos de la otra base de datos, ¿verdad?
Buttle Butkus
6

En lugar de mysql_connect, use mysqli_connect .

mysqli proporciona una funcionalidad para conectar múltiples bases de datos a la vez.

$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
fuente
1
$ hostname = 'Your DB_Hostname'; $ username = 'Your DB_Username'; $ contraseña = 'Su DB_password'; $ db_name1 = 'Su DB_Name 1'; $ db_name2 = 'Su DB_Name 2';
kaushik
Simplemente está mal que esto no funcionemysql_connect
Nico Haase
4

Pruebe el siguiente código:

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

Puede obtener datos de la consulta anterior de ambas bases de datos como se muestra a continuación

$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
fuente
Las dos consultas dadas funcionarían de la misma manera sin llamar mysql_select_dbni una sola vez; también, llamar dos veces sin nada más en el medio es inútil
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);

Esta es la solución más obvia que uso, pero solo recuerde, si el nombre de usuario / contraseña para ambas bases de datos es exactamente el mismo en el mismo host, esta solución siempre usará la primera conexión. Así que no se confunda que esto no está funcionando en tal caso. Lo que debe hacer es crear 2 usuarios diferentes para las 2 bases de datos y funcionará.

Compañero perezoso
fuente
3

A menos que realmente necesite tener más de una instancia de un objeto PDO en juego, considere lo siguiente:

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

Note la ausencia de dbname= en los argumentos de construcción.

Cuando se conecta a MySQL a través de un terminal u otra herramienta, el nombre de la base de datos no es necesario de inmediato. Puede cambiar entre bases de datos mediante el uso de la USE dbnamedeclaración a través del PDO::exec()método.

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

Por supuesto, es posible que desee envolver esto en una declaración catch try.

Michael Ratcliffe
fuente
Para aquellos que probarían el enfoque anterior, eche un vistazo antes de ese stackoverflow.com/a/14933070/1623579
TheFrost
¡Amo esta solución! Puedo prescindir de la configuración persistente, pero la creación de instancias de PDO es una gran solución. Obtiene una conexión predeterminada sin estar conectado a una base de datos específica.
Chuck Burgess
2

Es posible que pueda usar la sintaxis de MySQLi, lo que le permitiría manejarlo mejor.

Defina las conexiones de la base de datos, luego, cada vez que desee consultar una de las bases de datos, especifique la conexión correcta.

P.ej:

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

Luego, para consultarlos en la misma página, use algo como:

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

Cambiar a MySQLi de esta manera lo ayudará.

usuario3857891
fuente
Mejore su sintaxis (esto no es un sms) y formatee su código con las herramientas (Ctrl + K, por ejemplo).
fedorqui 'SO deja de dañar'
2

En realidad no lo necesitas select_db. Puede enviar una consulta a dos bases de datos al mismo tiempo. Primero, otorgue una subvención DB1para seleccionar DB2por GRANT select ON DB2.* TO DB1@localhost;. A continuación, FLUSH PRIVILEGES;. Finalmente, puede hacer una 'consulta de base de datos múltiple' como SELECT DB1.TABLE1.id, DB2.TABLE1.username FROM DB1,DB2etc. (No olvide que necesita acceso 'root' para usar el comando de concesión)

Nagibaba
fuente
1

si está utilizando mysqli y tiene dos archivos db_connection. como el primero es

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

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

el segundo es

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

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

SO simplemente cambia el nombre del paso de parámetros en mysqli como DB1 y DB2. si pasa el mismo parámetro en mysqli, suponga que DB1 en ambos archivos, la segunda base de datos ya no se conectará. Así que recuerde cuando use dos o más conexiones, pase un nombre de parámetro diferente en la función mysqli

Kamal Bunkar
fuente
-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
fuente
Para obtener más detalles, puede visitar github.com/sapankumarmohanty/CountRecordsAtMigrationFinalSync
htngapi