У меня есть информация, разбросанная по нескольким базам данных, и я хочу разместить всю информацию на одной веб-странице с помощью PHP. Мне было интересно, как я могу подключиться к нескольким базам данных на одной веб-странице PHP.
Я знаю, как подключиться к единой базе данных, используя:
$dbh = mysql_connect($hostname, $username, $password)
or die("Unable to connect to MySQL");
Однако могу ли я просто использовать несколько команд mysql_connect для открытия других баз данных, и как PHP узнает, из какой базы данных я хочу получить информацию, если у меня есть несколько подключенных баз данных.






Предупреждение : Функции mysql_xx устарели с php 5.5 и удалены с php 7.0 (см. http://php.net/manual/intro.mysql.php), используйте функции mysqli_xx или см. Ответ от @Troelskn ниже.
Вы можете сделать несколько вызовов mysql_connect(), но если параметры совпадают, вам необходимо передать true для параметра «$new_link» (четвертый), в противном случае то же соединение используется повторно. Например:
$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 есть доступ к обеим базам данных, и они находятся на одном хосте (т.е. обе БД доступны из одного и того же соединения), вы можете:
mysql_select_db(), чтобы при необходимости переключаться между ними. Я не уверен, что это чистое решение, и вы можете запросить неправильную базу данных.SELECT * FROM database2.tablename). Скорее всего, реализовать это будет сложно.Также прочитайте ответ troelskn, потому что это лучший подход, если вы можете использовать PDO, а не более старые расширения.
Можно ли установить один из них по умолчанию и просто добавить $dbh2 для второго только при необходимости? На то, чтобы изменить все запросы для этого подхода к работе, вероятно, потребуются дни, чтобы просто найти их все ...
@ThomasK, вы можете обернуть mysql_query в функцию с параметром по умолчанию, скажем, db_query($query,$db='db1'), а затем массово обновить все свои старые запросы до db_query($query) с последующим пользовательским обновлением ваших нестандартных запросов до db_query($query,'db2')
Используя ваш метод, какое соединение будет использоваться, если я определю два соединения, но не укажу, какое соединение использовать в запросе?
@Peter: согласно php.net/manual/en/function.mysql-query.php: If the link identifier is not specified, the last link opened by mysql_connect() is assumed.
Это правда спасло меня. Кто-нибудь может объяснить мне, почему, если я не укажу «истинно», я когда-либо подключаюсь к одной и той же базе данных?
Я знаю его старый пост, но если у кого-то из вас появляется ошибка аргумента mysqli_select_db() expects parameter 1 to be mysqli..., убедитесь, что соединение перед mysql_query($dbh1, 'select * from tablename');
Что делать с mysqli_connect
@Pratik Butani см. Другие ответы ниже, или лучше использовать PDO
Если вы используете 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();
}
Почему этого ответа нет наверху ?! Это правильный способ сделать это.
@aditya menon: На мой взгляд, правильный способ делать что-то часто не является правильным ответом на поставленный вопрос. спрашивающий не использовал PDO в своем вопросе, а использовал собственные функции mysql php, поэтому я считаю, что наиболее подходящий ответ будет следовать за кодом задающего вопроса.
@adityamenon, под чьим руководством? Помните, что пользователь всегда прав ... PDO - лучший способ, но оба способа - правильный способ решить проблему пользователей. Обратите внимание на разницу между правильным и лучшим. Да ... Мне скучно, поэтому мне пришлось сделать заявление.
Представляют ли $ db1 и $ db2 несколько соединений mysql? Если так, то это нехорошо. Есть ли способ разместить несколько баз данных всего за одно соединение?
@kavoir Зачем тебе это нужно? При необходимости вы можете изменить базу данных при текущем соединении с use DATABASENAME, но я не вижу в этом смысла?
@troelskn, потому что чем больше подключений mysql, тем медленнее? Поэтому я думаю, что лучше использовать только одно соединение для нескольких баз данных, чем создавать объект PDO для каждой из них, при условии, что они управляются одним пользователем mysql.
@kavoir Я бы не стал об этом беспокоиться. MySql очень эффективно обрабатывает соединения, так что это почти наверняка подоптимизация.
@troelskn "Зачем тебе это?" потому что, если у вас был доступ к нескольким базам данных с одним подключением, вы могли бы создать один запрос, который будет возвращать информацию из обеих баз данных одновременно, вместо того, чтобы делать несколько запросов и устанавливать несколько подключений, а затем сортировать результат для сопоставления нужной информации - что, как я понимаю, является задачей запросов к базе данных, чтобы сопоставить собранную информацию и получить легко используемые результаты ... видимо, вы знаете лучше, хотя
действительно ли необходимо знать «зачем ты хочешь это сделать?» ответ на каждый ответ? непонимание того, что делает другой разработчик, не означает, что для этого нет веских причин ...
Если вам действительно не нужно иметь более одного экземпляра объекта PDO в игре, примите во внимание следующее:
$con = new PDO('mysql:host=localhost', $username, $password,
array(PDO::ATTR_PERSISTENT => true));
Обратите внимание на отсутствие dbname= в аргументах конструкции.
Когда вы подключаетесь к MySQL через терминал или другой инструмент, имя базы данных сразу не требуется. Вы можете переключаться между базами данных с помощью оператора USE dbname через метод PDO::exec().
$con->exec("USE someDatabase");
$con->exec("USE anotherDatabase");
Конечно, вы можете заключить это в оператор catch try.
Для тех, кто попробует описанный выше подход, посмотрите перед этим stackoverflow.com/a/14933070/1623579
Обожаю это решение! Я могу обойтись без постоянной настройки, но создание экземпляра PDO - отличное решение. Вы получаете соединение по умолчанию без подключения к конкретной базе данных.
Попробуйте код ниже:
$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 ни разу - также бесполезно вызывать его дважды без чего-либо еще в середине.
$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);
Это наиболее очевидное решение, которое я использую, но просто помните, что если имя пользователя и пароль для обеих баз данных точно такие же на одном и том же хосте, это решение всегда будет использовать первое соединение. Так что пусть вас не смущает, что в таком случае это не работает. Что вам нужно сделать, так это создать двух разных пользователей для двух баз данных, и он будет работать.
Я просто упростил себе жизнь:
CREATE VIEW another_table AS SELECT * FROM another_database.another_table;
надеюсь, что это поможет ... ура ...
Это самое простое решение, если у вас нет таблиц с одинаковыми именами в обеих базах данных. Вы делаете это один раз, и вам больше не нужно беспокоиться о нескольких базах данных.
@ ErelSegal-Halevi, если вам нужен доступ только для чтения к данным из другой базы данных, верно?
Возможно, вы сможете использовать синтаксис 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).
Вместо mysql_connect используйте mysqli_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
$ hostname = 'Ваш DB_Hostname'; $ username = 'Ваше DB_Username'; $ password = 'Ваш DB_password'; $ db_name1 = 'Ваш DB_Name 1'; $ db_name2 = 'Ваш DB_Name 2';
Просто неправильно, что это не будет работать с mysql_connect
если вы используете 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**);
SO просто измените имя передачи параметра в mysqli, например DB1 и DB2. если вы передадите тот же параметр в mysqli, предположим, что DB1 в обоих файлах, вторая база данных больше не будет подключаться. Так что помните, когда вы используете два или более соединения, передайте другое имя параметра в функции mysqli.
На самом деле вам не нужен select_db. Вы можете отправить запрос в две базы данных одновременно. Во-первых, предоставьте DB1 право выбора из DB2 по GRANT select ON DB2.* TO DB1@localhost;. Затем FLUSH PRIVILEGES;. Наконец, вы можете выполнять «запрос к нескольким базам данных», например SELECT DB1.TABLE1.id, DB2.TABLE1.username FROM DB1,DB2 и т. д. (Не забывайте, что вам нужен «root» доступ для использования команды grant)
<?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/>----------------------------------------";
}
}
?>
Для более подробной информации вы можете посетить github.com/sapankumarmohanty/CountRecordsAtMigrationFinalSyn c
+1 У меня это решение сработало. После двух дней отладки, почему мои пользовательские шаблоны WordPress теряли доступ к объекту $ WP_Query после вызова второго подключения к базе данных ...