如何在单个网页上连接多个MySQL数据库?

182

我有一些信息分散在几个数据库中,想使用PHP将所有信息放到一个网页上。我想知道如何在单个PHP页面上连接多个数据库。

我知道如何连接单个数据库:

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

然而,我能否只使用多个 "mysql_connect" 命令来打开其他数据库? 如果我确实连接了多个数据库,PHP如何知道我希望从哪个数据库中提取信息。

11个回答

339

注意:mysql_xx函数已自php 5.5起被弃用,自php 7.0起被删除(请参阅http://php.net/manual/intro.mysql.php),请使用mysqli_xx函数或参考@Troelskn的答案。


您可以多次调用mysql_connect(),但如果参数相同,则需要为'$new_link'(第四个)参数传递true,否则将重用相同的连接。例如:

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

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

然后要查询数据库1,请传递第一个链接标识符:

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

并且对于数据库 2,通过第二个:

mysql_query('select * from tablename', $dbh2);
如果您没有传递链接标识符,则会使用上次创建的连接(在这种情况下,由$dbh2表示)例如:
mysql_query('select * from tablename');

其他选项

如果MySQL用户可以访问两个数据库,并且它们在同一主机上(即从同一个连接可以访问两个DB),你可以:

  • 保持一个连接打开,并在必要时调用mysql_select_db()进行切换。我不确定这是否是一个干净的解决方案,你可能会查询错误的数据库。
  • 在查询中引用表时指定数据库名称(例如:SELECT * FROM database2.tablename)。这可能很麻烦。

此外,请阅读troelskn的答案,因为如果您能够使用PDO而不是较旧的扩展名,则这是更好的方法。


2
+1 这个解决方案对我很有用。在经过两天的调试后,我终于找到了原因:我的自定义WordPress模板在第二个数据库连接调用后失去了对$WP_Query对象的访问权限... - Edward J Beckett
有没有可能将它们中的一个设置为默认值,只有在需要第二个时才添加$dbh2?更改所有查询以使此方法起作用可能需要数天时间,仅查找所有查询就够了... - ThomasK
1
@Peter:根据http://php.net/manual/en/function.mysql-query.php的说明:`如果未指定链接标识符,则假定为mysql_connect()打开的最后一个链接。` - Tom Haigh
那个“true”确实救了我。有人能解释一下为什么如果我不加上“true”,我每次都连接到同一个数据库吗? - Overnet
@Pratik Butani,请查看下面的其他答案,或者更好地使用PDO。 - Tom Haigh
显示剩余4条评论

102

如果您使用PHP5(应该这样做,因为PHP4已经被弃用),您应该使用PDO,因为它正在逐渐成为新标准。 PDO的一个(非常)重要的好处是,它支持绑定参数,这可以使代码更加安全。

连接PDO的方式如下:

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

(当然,以上要替换为数据库名称、用户名和密码)

您可以像这样查询数据库:

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

或者,如果您有变量:

$stmt = $db->prepare("select * from tablename where id = :id");
$stmt->execute(array(':id' => 42));
$row = $stmt->fetch();
如果您需要同时打开多个连接,您可以简单地创建多个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
为什么这个答案不在最前面?!这是正确的处理方式。 - Aditya M P
10
在我看来,正确的做事方式通常并不是解决问题的正确答案。问答者在他的问题中没有使用 PDO,而是用 PHP 本地的 MySQL 函数,所以我认为最合适的答案应该跟随问答者的代码。 - Jonathan DS
2
@adityamenon 在谁的授权下?请记住用户永远是正确的... PDO 是最好的方式,但两种方式都是解决用户问题的正确方式。请注意“正确”和“最好”的区别。是的...我很无聊,所以我不得不发表一番声明。 - JustinKaz
$db1和$db2代表多个mysql连接吗?如果是这样的话,那就不太好。有没有办法只用一个连接来容纳多个数据库? - datasn.io
@kavoir 你为什么想要那个?如果需要的话,你可以使用 use DATABASENAME 在当前连接上更改数据库,但我不明白这有什么意义? - troelskn
显示剩余4条评论

10

我刚刚让我的生活变得简单:

CREATE VIEW another_table AS SELECT * FROM another_database.another_table;

希望它有所帮助... 干杯...


1
如果您在两个数据库中没有相同名称的表,则此解决方案是最简单的。只需执行一次即可,然后您就不必再担心多个数据库了。 - Erel Segal-Halevi
只要您只需要从其他数据库中获得只读访问权限,对吗? - Buttle Butkus

7

使用mysqli_connect代替mysql_connect

mysqli提供了同时连接多个数据库的功能。

$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 = '您的DB_Hostname'; $username = '您的DB_Username'; $password = '您的DB_password'; $db_name1 = '您的DB_Name 1'; $db_name2 = '您的DB_Name 2'; - kaushik
这不应该是错误的,使用mysql_connect却无法工作。 - Nico Haase

5
尝试以下代码:

尝试以下代码:

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

你可以从以下两个数据库中获取上述查询的数据:
$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);

即使没有调用mysql_select_db,给定的两个查询也会以相同的方式工作 - 同时,在中间什么也没有的情况下连续调用两次是无用的。 - 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);

这是我使用的最明显的解决方案,但请记住,如果在同一主机上两个数据库的用户名/密码完全相同,此解决方案将始终使用第一个连接。因此,在这种情况下不要感到困惑,认为它无法工作。您需要做的是为两个数据库创建2个不同的用户,然后它就可以工作了。


3

如果您没有必要同时使用多个PDO对象的话,请考虑以下内容:

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

请注意,在构造参数中缺少dbname=
当您通过终端或其他工具连接到MySQL时,数据库名称并不是必需的。您可以通过使用PDO::exec()方法中的USE dbname语句在不同的数据库之间切换。
$con->exec("USE someDatabase");
$con->exec("USE anotherDatabase");

当然,您可能希望将此内容包装在try-catch语句中。

对于那些想尝试上述方法的人,请先查看以下链接:http://stackoverflow.com/a/14933070/1623579 - TheFrost
我喜欢这个解决方案!我可以不用持久设置,但是PDO的实例化是一个很好的解决方案。你可以获得一个默认连接而不必连接到特定的数据库。 - Chuck Burgess

2

您实际上不需要使用 select_db。您可以同时向两个数据库发送查询。首先,通过 GRANT select ON DB2.* TO DB1@localhost;DB1 授予从 DB2 选择的权限。然后,执行 FLUSH PRIVILEGES;。最后,您可以执行“多数据库查询”,例如 SELECT DB1.TABLE1.id, DB2.TABLE1.username FROM DB1,DB2 等等(请注意,您需要 'root' 访问权限才能使用授权命令)。


2

您可能可以使用MySQLi语法,这将使您更好地处理它。

定义数据库连接,然后每当您想要查询其中一个数据库时,请指定正确的连接。

例如:

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

然后,要在同一页上查询它们,请使用以下内容:
$query = $Db1->query("select * from tablename")
$query2 = $Db2->query("select * from tablename")
die("$Db1->error");

以这种方式更改为MySQLi将对您有所帮助。


请改进您的语法(这不是短信),并使用工具格式化您的代码(例如Ctrl+K)。 - fedorqui

1

如果您正在使用mysqli并且有两个db_connection文件,例如第一个文件是:

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

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

第二个是什么?
    define('HOST','localhost');
    define('USER','user');
    define('PASS','passs');
    define(**'DB2**','database_name1');

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

所以,只需更改mysqli中传递的参数名称,例如DB1和DB2。 如果在mysqli中传递相同的参数(如DB1)到两个文件中,则第二个数据库将不再连接。因此,请记住,在使用两个或更多连接时,请在mysqli函数中传递不同的参数名称。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接