2008-11-08 32 views
167

Tôi có thông tin trải rộng trên một vài cơ sở dữ liệu và muốn đưa tất cả thông tin vào một trang web bằng cách sử dụng PHP. Tôi đã tự hỏi làm thế nào tôi có thể kết nối với nhiều cơ sở dữ liệu trên một trang web PHP duy nhất.Làm thế nào để bạn kết nối với nhiều cơ sở dữ liệu MySQL trên một trang web?

tôi biết làm thế nào để kết nối với một cơ sở dữ liệu đơn sử dụng:

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

Tuy nhiên, tôi có thể chỉ cần sử dụng nhiều "mysql_connect" lệnh để mở cơ sở dữ liệu khác, và làm thế nào sẽ PHP biết cơ sở dữ liệu tôi muốn thông tin kéo từ nếu tôi có nhiều cơ sở dữ liệu được kết nối.

Trả lời

312

Bạn có thể thực hiện nhiều cuộc gọi đến mysql_connect(), nhưng nếu các thông số giống nhau, bạn cần chuyển đúng cho tham số '$new_link' (thứ tư), nếu không kết nối đó sẽ được sử dụng lại. Ví dụ:

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

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

Sau đó, để truy vấn cơ sở dữ liệu 1 vượt qua định danh liên kết đầu tiên:

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

và cho cơ sở dữ liệu 2 vượt qua thứ hai:

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

Nếu bạn không vượt qua một liên kết số nhận dạng sau đó kết nối cuối cùng được tạo được sử dụng (trong trường hợp này, số được đại diện bởi $dbh2) ví dụ:

mysql_query('select * from tablename'); 

Các tùy chọn khác

Nếu người dùng MySQL có quyền truy cập vào cả hai cơ sở dữ liệu và họ đang ở trên cùng một máy chủ (ví dụ: cả hai DB đều có thể truy cập từ cùng một kết nối), bạn có thể:

  • Giữ một kết nối mở và gọi mysql_select_db() để trao đổi giữa khi cần thiết. Tôi không chắc chắn đây là một giải pháp sạch sẽ và bạn có thể kết thúc truy vấn cơ sở dữ liệu sai.
  • Chỉ định tên cơ sở dữ liệu khi bạn tham chiếu các bảng trong truy vấn của mình (ví dụ: SELECT * FROM database2.tablename). Đây có thể là một nỗi đau để thực hiện.

Cũng vui lòng đọc câu trả lời của troelskn vì đó là cách tiếp cận tốt hơn nếu bạn có thể sử dụng PDO thay vì các tiện ích mở rộng cũ hơn.

+37

rằng "true" vừa tiết kiệm cho tôi số giờ làm việc – PurplePilot

+2

+1 Giải pháp này làm việc cho tôi. Sau hai ngày gỡ lỗi vì sao các mẫu WordPress tùy chỉnh của tôi mất quyền truy cập đối tượng $ WP_Query sau khi gọi đến kết nối cơ sở dữ liệu thứ hai ... –

+0

có thể đặt một trong số chúng thành mặc định và chỉ cần thêm ' $ dbh2' cho cái thứ hai chỉ khi cần? Phải thay đổi tất cả các truy vấn cho cách tiếp cận này để làm việc có thể mất vài ngày để tìm tất cả chúng ... – ThomasK

3

Bạn cũng có thể muốn xem xét một trong nhiều công cụ trừu tượng hóa cơ sở dữ liệu xung quanh. Tuy nhiên, họ thường sẽ làm điều tương tự mà tom mô tả để giữ cho nhiều kết nối mở cùng một lúc.

87

Nếu bạn sử dụng PHP5 (Và bạn nên, cho rằng PHP4 đã không được chấp nhận), bạn nên sử dụng PDO, vì điều này đang dần trở thành tiêu chuẩn mới. Một (rất) lợi ích quan trọng của PDO, là nó hỗ trợ các tham số ràng buộc, làm cho mã an toàn hơn nhiều.

Bạn sẽ kết nối thông qua PDO, như thế này:

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

(Tất nhiên thay databasename, tên người dùng và mật khẩu ở trên)

Sau đó bạn có thể truy vấn cơ sở dữ liệu như thế này:

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

Hoặc, nếu bạn có các biến:

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

Nếu bạn cần nhiều kết nối mở cùng một lúc, bạn chỉ có thể tạo ra nhiều trường hợp của 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

Tại sao câu trả lời này không nằm ở trên cùng ?! Đây là cách chính xác để đi về nó. –

+8

@aditya menon theo ý kiến ​​của tôi, đúng cách để làm điều gì đó thường không phải là câu trả lời đúng cho câu hỏi trong tầm tay. Asker đã không sử dụng PDO trong câu hỏi của mình nhưng các hàm mysql bản địa của php, vì vậy tôi tin rằng câu trả lời phù hợp nhất sẽ tuân theo mã người hỏi. – Jonathan

+2

@adityamenon thuộc thẩm quyền của ai? Hãy nhớ rằng người dùng luôn đúng ... PDO là cách tốt nhất, nhưng cả hai cách là đúng cách để giải quyết vấn đề người dùng. Xin lưu ý sự khác biệt giữa phải và tốt nhất. Vâng ... Tôi chán nên tôi phải đưa ra một tuyên bố. – JustinKaz

3

Trừ khi bạn thực sự cần phải có nhiều hơn một thể hiện của một đối tượng PDO trong vở kịch, xem xét như sau:

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

Lưu ý sự vắng mặt của dbname= trong đối số xây dựng.

Khi bạn kết nối với MySQL thông qua thiết bị đầu cuối hoặc công cụ khác, tên cơ sở dữ liệu không cần thiết. Bạn có thể chuyển đổi giữa các cơ sở dữ liệu bằng cách sử dụng câu lệnh USE dbname qua phương thức PDO::exec().

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

Tất nhiên bạn có thể muốn bọc phần này trong câu lệnh thử bắt.

+0

Đối với những người, những người sẽ thử phương pháp tiếp cận trên, hãy xem trước đó http://stackoverflow.com/ a/14933070/1623579 – TheFrost

+0

Tôi thích giải pháp này! Tôi có thể làm mà không cần thiết lập liên tục, nhưng sự khởi tạo của PDO là một giải pháp tuyệt vời. Bạn nhận được kết nối mặc định mà không được kết nối với cơ sở dữ liệu cụ thể. –

5

Hãy thử bên dưới mã:

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

Bạn có thể lấy dữ liệu truy vấn trên từ cả hai cơ sở dữ liệu như sau

$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); 
2
$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); 

Đây là giải pháp rõ ràng nhất mà tôi sử dụng nhưng hãy nhớ, nếu tên người dùng/mật khẩu cho cả hai cơ sở dữ liệu là chính xác giống nhau trong cùng một máy chủ, giải pháp này sẽ luôn luôn được sử dụng kết nối đầu tiên. Vì vậy, đừng nhầm lẫn rằng điều này không hoạt động trong trường hợp này. Những gì bạn cần làm là tạo 2 người dùng khác nhau cho 2 cơ sở dữ liệu và nó sẽ hoạt động.

8

Tôi chỉ làm cho cuộc sống của tôi rất đơn giản:

CREATE VIEW another_table AS SELECT * FROM another_database.another_table; 

hy vọng nó là hữu ích ... chúc mừng ...

+1

Đây là giải pháp dễ nhất nếu bạn không có bảng có cùng tên trong cả hai cơ sở dữ liệu. Bạn làm điều đó một lần, và sau đó bạn không phải lo lắng về nhiều cơ sở dữ liệu nữa. –

1

Bạn có thể có thể sử dụng cú pháp MySQLi, mà sẽ cho phép bạn xử lý nó tốt hơn .

Xác định kết nối cơ sở dữ liệu, sau đó bất cứ khi nào bạn muốn truy vấn một trong các cơ sở dữ liệu, hãy chỉ định kết nối phù hợp.

ví dụ .:

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

Sau đó, để truy vấn họ trên cùng một trang, sử dụng một cái gì đó như:

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

Thay đổi để MySQLi theo cách này sẽ giúp bạn.

+0

Vui lòng cải thiện cú pháp của bạn (đây không phải là một tin nhắn SMS) và định dạng mã của bạn bằng các công cụ (ví dụ: Ctrl + K). – fedorqui

6

Thay vì mysql_connect sử dụng mysqli_connect.

mysqli cung cấp chức năng kết nối nhiều cơ sở dữ liệu cùng một lúc.

$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 của bạn'; $ password = 'DB_password của bạn'; $ db_name1 = 'DB_Name của bạn 1'; $ db_name2 = 'DB_Name 2 của bạn'; – kaushik

1

nếu bạn đang sử dụng mysqli và có hai tệp db_connection. như Đầu tiên là

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

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

thứ hai là

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

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

SO chỉ cần thay đổi tên của tham số đường chuyền trong mysqli như DB1 và ​​DB2. nếu bạn vượt qua cùng một tham số trong mysqli giả sử DB1 trong cả hai tệp thì cơ sở dữ liệu thứ hai sẽ không kết nối nữa. Vì vậy, hãy nhớ khi bạn sử dụng hai hoặc nhiều kết nối vượt qua tên thông số khác nhau trong hàm mysqli

1

Bạn không thực sự cần select_db. Bạn có thể gửi một truy vấn đến hai cơ sở dữ liệu cùng một lúc. Trước tiên, hãy cấp khoản tiền cho số DB1 để chọn từ DB2 theo GRANT select ON DB2.* TO [email protected];. Sau đó, FLUSH PRIVILEGES;. Cuối cùng, bạn có thể thực hiện 'truy vấn nhiều cơ sở dữ liệu' như SELECT DB1.TABLE1.id, DB2.TABLE1.username FROM DB1,DB2 v.v. (Đừng quên rằng bạn cần quyền truy cập 'root' để sử dụng lệnh cấp)

Các vấn đề liên quan