182

I have information spread out across a few databases and want to put all the information onto one webpage using PHP. I was wondering how I can connect to multiple databases on a single PHP webpage.

I know how to connect to a single database using:

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

However, can I just use multiple "mysql_connect" commands to open the other databases, and how would PHP know what database I want the information pulled from if I do have multiple databases connected.

Gilles 'SO- stop being evil'
  • 104,111
  • 38
  • 209
  • 254
JoshFinnie
  • 4,841
  • 7
  • 28
  • 28

11 Answers11

339

Warning : mysql_xx functions are deprecated since php 5.5 and removed since php 7.0 (see http://php.net/manual/intro.mysql.php), use mysqli_xx functions or see the answer below from @Troelskn


You can make multiple calls to mysql_connect(), but if the parameters are the same you need to pass true for the '$new_link' (fourth) parameter, otherwise the same connection is reused. For example:

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

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

Then to query database 1 pass the first link identifier:

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

and for database 2 pass the second:

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

If you do not pass a link identifier then the last connection created is used (in this case the one represented by $dbh2) e.g.:

mysql_query('select * from tablename');

Other options

If the MySQL user has access to both databases and they are on the same host (i.e. both DBs are accessible from the same connection) you could:

  • Keep one connection open and call mysql_select_db() to swap between as necessary. I am not sure this is a clean solution and you could end up querying the wrong database.
  • Specify the database name when you reference tables within your queries (e.g. SELECT * FROM database2.tablename). This is likely to be a pain to implement.

Also please read troelskn's answer because that is a better approach if you are able to use PDO rather than the older extensions.

ᴄʀᴏᴢᴇᴛ
  • 2,939
  • 26
  • 44
Tom Haigh
  • 57,217
  • 21
  • 114
  • 142
  • 2
    +1 This solution worked for me. After two days of debugging why my custom WordPress templates were losing access to the $WP_Query object after a call to the second database connection ... – Edward J Beckett May 04 '12 at 23:22
  • is it possible to set one of them to be the default one, and just having to add `$dbh2` for the second one only when needed? Having to change all queries for this approach to work would probably take days just finding all of them... – ThomasK Aug 08 '12 at 11:26
  • @ThomasK, you could wrap mysql_query in a function with a default parameter, say, `db_query($query,$db='db1')` and then mass update all your old queries to `db_query($query)` followed by custom updating your non-default ones to `db_query($query,'db2')` – joshuahedlund Nov 21 '12 at 15:46
  • Using your method, which connection will be used if I define two connections but do not specify which connection to use at the query? – Peter Nov 05 '14 at 10:28
  • 1
    @Peter: according to http://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 Nov 05 '14 at 13:03
  • That true have save me. Anyone can explain me why if I don't put the "true" I connect ever to the same database? – Overnet Dec 16 '15 at 18:24
  • I know its old post, but if any of you get a argument error `mysqli_select_db() expects parameter 1 to be mysqli...` then make sure the connection is in front `mysql_query($dbh1, 'select * from tablename');` – Dexter Mar 07 '18 at 14:42
  • What to do with `mysqli_connect` – Pratik Butani Jan 04 '20 at 06:49
  • @Pratik Butani see other answers below, or better, use PDO – Tom Haigh Mar 17 '20 at 08:22
102

If you use PHP5 (And you should, given that PHP4 has been deprecated), you should use PDO, since this is slowly becoming the new standard. One (very) important benefit of PDO, is that it supports bound parameters, which makes for much more secure code.

You would connect through PDO, like this:

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

(Of course replace databasename, username and password above)

You can then query the database like this:

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

Or, if you have variables:

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

If you need multiple connections open at once, you can simply create multiple instances of 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();
}
Saul
  • 17,973
  • 8
  • 64
  • 88
troelskn
  • 115,121
  • 27
  • 131
  • 155
  • 5
    Why isn't this answer at the top?! This is the correct way to go about it. – Aditya M P Oct 17 '11 at 04:05
  • 10
    @aditya menon in my opinion, the right way to do something often is not the right answer to the question at hand. the Asker was not using PDO in his question but php native mysql functions, so i believe the fittest answer would follow the asker code. – Jonathan DS Mar 29 '12 at 22:36
  • 2
    @adityamenon under whose authority? Remember the user is always right... PDO is the best way, but both ways are the right way to solve the users problem. Please note the difference between right and best. Yes... I'm bored so I had to make a statement. – JustinKaz Apr 02 '12 at 01:09
  • Do $db1 and $db2 represent multiple mysql connections? If so, that's not good. Is there any way to accommodate multiple databases with just one connection? – datasn.io Sep 08 '14 at 01:18
  • @kavoir Why would you want that? If need be, you could change the database on the current connection with `use DATABASENAME`, but I don't see the point? – troelskn Sep 08 '14 at 11:49
  • @troelskn, because the more mysql connections, the slower? So I guess it should be better to use just one connection for multiple databases rather than creating a PDO object for each of them, provided they are managed by a single mysql user. – datasn.io Sep 08 '14 at 13:38
  • @kavoir I wouldn't worry about that. MySql is very efficient about handling connections, so that is almost certainly a sub-optimisation. – troelskn Sep 09 '14 at 07:22
  • @troelskn "Why would you want that?" because if you had access to multiple databases with a single connection you could create a single query that would return information from both databases simultaneously, rather than making multiple queries and establishing multiple connections, and then sorting through the result to collate the information you want--which, as i understand it, is the job of database queries, to collate information gleaned into easily usable results... apparently you know better though – me_ Dec 23 '17 at 03:09
  • is it really necessary to have the "why do you want to do that?" response on every answer? not understanding what another developer is doing doesn't mean there isn't good cause to want to do it.... – me_ Dec 23 '17 at 03:11
10

I just made my life simple:

CREATE VIEW another_table AS SELECT * FROM another_database.another_table;

hope it is helpful... cheers...

Mihai
  • 26,325
  • 7
  • 66
  • 81
Ihsan Kusasi
  • 646
  • 7
  • 3
  • 1
    This is the easiest solution if you do not have tables with the same name in both databases. You do it once, and then you do not have to worry about multiple databases any more. – Erel Segal-Halevi Aug 05 '16 at 08:15
  • @ErelSegal-Halevi as long as you need only read-only access to the data from the other db, right? – Buttle Butkus Jan 09 '19 at 22:44
7

Instead of mysql_connect use mysqli_connect.

mysqli is provide a functionality for connect multiple database at a time.

$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
ahmetertem
  • 242
  • 6
  • 14
kaushik
  • 903
  • 7
  • 16
  • 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 Apr 20 '15 at 03:55
  • It just wrong that this would not work with `mysql_connect` – Nico Haase Sep 17 '18 at 06:51
5

Try below code:

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

You can fetch data of above query from both database as below

$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
  • 101
  • 2
  • 11
  • The given two queries would work the same way without calling `mysql_select_db` even once - also, calling it twice without anything else in the middle is useless – Nico Haase Sep 17 '18 at 06:52
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);

This is the most obvious solution that I use but just remember, if the username / password for both the database is exactly same in the same host, this solution will always be using the first connection. So don't be confused that this is not working in such case. What you need to do is, create 2 different users for the 2 databases and it will work.

Andrea php
  • 393
  • 4
  • 21
3

Unless you really need to have more than one instance of a PDO object in play, consider the following:

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

Notice the absence of dbname= in the construction arguments.

When you connect to MySQL via a terminal or other tool, the database name is not needed off the bat. You can switch between databases by using the USE dbname statement via the PDO::exec() method.

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

Of course you may want to wrap this in a catch try statement.

Littm
  • 4,923
  • 4
  • 30
  • 38
  • For those, who would try above approach, take a look on before that http://stackoverflow.com/a/14933070/1623579 – TheFrost Oct 20 '13 at 16:10
  • I love this solution! I can do without the persistent setting, but the instantiation of PDO is a great solution. You get a default connection without being connected to a specific database. – Chuck Burgess Oct 29 '15 at 19:46
2

You might be able to use MySQLi syntax, which would allow you to handle it better.

Define the database connections, then whenever you want to query one of the database, specify the right connection.

E.g.:

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

Then to query them on the same page, use something like:

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

Changing to MySQLi in this way will help you.

hcarver
  • 7,126
  • 4
  • 41
  • 67
  • Please improve your syntax (this is not a sms) and format your code with the tools (Ctrl+K, for example). – fedorqui Aug 04 '14 at 08:12
2

You don't actually need select_db. You can send a query to two databases at the same time. First, give a grant to DB1 to select from DB2 by GRANT select ON DB2.* TO DB1@localhost;. Then, FLUSH PRIVILEGES;. Finally, you are able to do 'multiple-database query' like SELECT DB1.TABLE1.id, DB2.TABLE1.username FROM DB1,DB2 etc. (Don't forget that you need 'root' access to use grant command)

Nagibaba
  • 4,218
  • 1
  • 35
  • 43
1

if you are using mysqli and have two db_connection file. like first one is

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

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

second one is

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

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

SO just change the name of parameter pass in mysqli like DB1 and DB2. if you pass same parameter in mysqli suppose DB1 in both file then second database will no connect any more. So remember when you use two or more connection pass different parameter name in mysqli function

Kamal Bunkar
  • 1,354
  • 1
  • 16
  • 20
-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/>----------------------------------------";

        }     

    }
    ?>
htngapi
  • 365
  • 3
  • 7
  • For More details you can visit https://github.com/sapankumarmohanty/CountRecordsAtMigrationFinalSync – htngapi Apr 29 '19 at 08:35