Фон
У меня есть проект, который разрабатывался около нескольких лет.Большая часть кода устарела и использует старый стиль программирования.Теперь я изменил структуру базы данных.Я переместил некоторые таблицы в новую базу данных, которые все еще находятся на том же сервере.
Есть много функций mysql_*
, оставшихся без заданного ресурса базы данных ($link
не установлено).В важных случаях я уже заменил доступ к базе данных более новым стилем программирования, но из-за массы кода я не могу просто заменить все mysql_*
функции.
Вопрос
Проблема в том, что все mysql_*
функции без предоставленного ресурса будут подключаться к последней открытой базе данных.В моем случае последняя открытая база данных - это неправильная база данных.Я хочу изменить это соединение по умолчанию.
Некоторый код для лучшего понимания
// old database, new connection is forced
$db1 = mysql_connect($hostname, $username, $password, true);
// new database, new connection is forced
$db2 = mysql_connect($hostname, $username, $password, true);
mysql_select_db($dbn1, $db1);
mysql_select_db($dbn2, $db2);
Оба соединения с базой данных имеют одинаковые $hostname
, одинаковые $username
и тот же $password
.Они различаются только в базе данных ($dbn1
и $dbn2
).
mysql_query("SELECT DATABASE();", $db1); // $dbn1
mysql_query("SELECT DATABASE();", $db2); // $dbn2
mysql_query("SELECT DATABASE();"); // $dbn2 <- this should be changed
База данных (без заданного ресурса) теперь будет иметь последнее соединение, которое является $db2
.Но для обратной совместимости я хочу, чтобы это было $db1
.
Уже испробованные решения
Изменить базу данных
Теперь я просто хотел изменитьбаза данных.
mysql_select_db($dbn1, $db1);
mysql_query("SELECT DATABASE();", $db1); // $dbn1
mysql_query("SELECT DATABASE();", $db2); // $dbn2
mysql_query("SELECT DATABASE();"); // $dbn2 <- still the same
При выборе базы данных с данным ресурсом последнее соединение (очевидно) не меняется.Это означает, что для вызовов функций с пропущенным параметром $link
база данных по-прежнему неверна.
Изменить базу данных (без параметра $link
)
mysql_select_db($dbn1); // no $link parameter
mysql_query("SELECT DATABASE();", $db1); // $dbn1
mysql_query("SELECT DATABASE();", $db2); // $dbn1 <- now this is wrong
mysql_query("SELECT DATABASE();"); // $dbn1
Изменениебаза данных без параметра $link
изменяет базу данных $db2
.Даже если они вынуждены к новому объекту ресурса.(Объекты ресурсов разные, я их проверил.) Повторное подключение $db2
к базе данных $dbn2
(с заданным $link
) снова изменит последнее подключение (последний запрос).
Таким образом, изменение базы данныхне меняет ресурс $link
, что имеет смысл.Так что переменная $link
, хранящаяся в php для функций mysql_*
, неверна.
Повторное открытие соединения
$db1 = mysql_connect($hostname, $username, $password);
mysql_select_db($dbn1, $db1);
mysql_query("SELECT DATABASE();", $db1); // $dbn1
mysql_query("SELECT DATABASE();", $db2); // $dbn1 <- now this is wrong again
mysql_query("SELECT DATABASE();"); // $dbn1
Я пытался создатьновое соединение без форсирования нового $link
.Таким образом, последнее созданное соединение - это соединение, которое я хочу.Но теперь $db2
не так.Это также имеет смысл, поскольку $db1
и $db2
находятся на одном сервере.Открытие нового соединения с теми же данными и не форсирование нового соединения, конечно, перезапишет их обоих (я не проверял это).
Супер уродливое и грязное решение
Единственное решение, которое я нашел, - это воссоздать соединение для $db2
, а затем заново воссоздать соединение для $db1
.Поэтому я снова и снова создаю соединения с базой данных.Код (обобщенный и упрощенный, конечно, не в одном файле. Также я не могу просто удалить первые строки!) Выглядит так:
// the $db1 and $db2 are created elsewhere so they will always exist
$db1 = mysql_connect($hostname, $username, $password, true);
$db2 = mysql_connect($hostname, $username, $password, true);
mysql_select_db($dbn1, $db1);
mysql_select_db($dbn2, $db2);
// in the actual database files before accessing the database
$db2 = mysql_connect($hostname, $username, $password);
mysql_select_db($dbn2, $db2);
$db1 = mysql_connect($hostname, $username, $password, true);
mysql_select_db($dbn1, $db1);
Но на мой взгляд это выглядит ужасно и избыточно.Проблема в том, что объекты базы данных $db1
и $db1
очень часто используются также в асинхронных запросах AJAX.Иногда есть только один из ресурсов базы данных.
Кроме того, последние 4 строки приведенного выше кода должны выполняться перед каждым запросом $db1
или после каждого запроса $db2
.Для меня это кажется огромным беспорядком.
Итак, мой общий вопрос : Кто-нибудь знает, как я могу это исправить?
Примечание: Замена всех функций не вариант.Также я знаю, что mysql
устарела и удалена в PHP 7, но опять же я не могу заменить функции.Также невозможно просто создать $db2
до $db1
.Оба соединения с базой данных создаются в разных точках кода или параллельно в запросах ajax независимо друг от друга.Просто невозможно гарантировать порядок создания.Кроме того, мне нужны данные из $db1
для использования $db2
.
Редактировать
Кроме того, последние 4 строки приведенного выше кода должны выполняться перед каждым запросом $db1
или после каждого запроса $db2
.
Чтобы уточнить эту строку: В кодетакже есть класс Database
.Существует один объект $database
для базы данных 1 и соединения $db1
и один объект для $new_database
для базы данных 2 и соединения $db2
.
Сначала было только одно соединение с базой данных.По этой причине предыдущие программисты просто писали такие вещи:
$sql = "SELECT * FROM `example_table` WHERE id = 100;";
$result = mysql_query($query);
$result = mysql_fetch_assoc($result);
Затем был изобретен класс Database
.Теперь написанный код выглядит так:
$database->setQuery("SELECT * FROM `example_table` WHERE id = 100;");
$result = $database->getAssocResult();
Теперь мы ввели другую базу данных.Теперь есть также строки с
$new_database->setQuery(...);
...
Все эти варианты существуют параллельно в коде.В 10 000 разных файлов огромное количество строк.База данных 2 всегда и только используется вместе с классом Database
и объектом $new_database
.В цитируемой строке я говорю об изменении класса Database
.
class Database{
protected function query(){
// handle the actual query stuff
global $db1, $dbn1, $dbn2;
if($this->database_name == $dbn2){
$this->link = mysql_connect($this->hostname, $this->username, $this->password);
mysql_select_db($dbn2, $this->link);
$db1 = mysql_connect($this->hostname, $this->username, $this->password, true);
mysql_select_db($dbn1, $db1);
}
return $result;
}
}
Таким образом, соединение базы данных с $db1
всегда будет сброшено к старой базе данных.Теперь можно использовать функции mysql_*
.Но это решение очень уродливо, как я уже сказал.