Задать вопрос
liaren
@liaren
Фрилансер, опенсорсер, тех лид

Расширение mysql для PHP путает ссылки на соединения к разным базам одного сервера

Я был просто в шоке, что этот код в обоих случаях возвращает данные из базы sh2

<?php

$conn1 = mysql_pconnect('localhost', 'root', '');
$conn2 = mysql_pconnect('localhost', 'root', '');

mysql_select_db('sh1', $conn1);
mysql_select_db('sh2', $conn2);

$res = mysql_query('SELECT * FROM users_collections', $conn1);
while($row = mysql_fetch_assoc($res)) {
print_r($row);
}

$res = mysql_query('SELECT * FROM users_collections', $conn2);
while($row = mysql_fetch_assoc($res)) {
print_r($row);
}


При чём если прописать $conn2 = mysql_pconnect('127.0.0.1', 'root', ''); то возвращаются данные разных баз.
Кто-нибудь знает как с этим бороться?

Нужно решение для функции подключения mysql_pconnect. Про четвёртый аргумент mysql_connect и так знаем.

// очевидные решения: использовать mysqli, или явным образом указывать в запросах имя базы не подходят :)
  • Вопрос задан
  • 2738 просмотров
Подписаться 2 Оценить Комментировать
Пригласить эксперта
Ответы на вопрос 7
BuriK666
@BuriK666
Компьютерный псих
В документации об этом написано
Если второй вызов функции mysql_connect() произошёл с теми же аргументами, то новое соединение не будет установлено. Вместо этого функция вернёт ссылку на уже установленное соединение.
ru.php.net/manual/ru/function.mysql-connect.php
Ответ написан
Комментировать
homm
@homm
В этом и смысл mysql_pconnect, возвращается уже существующее соединение. В шоке он.
Ответ написан
sdevalex
@sdevalex
А намного более разумно будет юзать PDO, mysql_* уже вроде выкинули из стандартного пакета. Это конечно, если вы пишите с нуля.
Ответ написан
Комментировать
@korvindest
Судя по вашему эксперименту со сменой localhost на 127.0.0.1 у вас не создается второго подключения к СУБД а возвращается ссылка на уже созданное (потому что они идентичны).
Поэтому активной для обоих(на сам ом деле одного) подключений является последняя выбранная база.
Думаю, если написать
mysql_select_db('sh2', $conn2);
mysql_select_db('sh1', $conn1);
то все запросы пойдут к sh1.
Вариантов решения море.
1. Сделать для каждой базы своего пользователя (это правильно со многих сторон)
2. Заставить СУБД слушать несколько портов и конектится к разным.
3. Сделать несколько псевдонимов localhost и указывать разные в подключениях.

P.S.
Это моя гипотеза, т.к. проверить сейчас не на чем, но мне кажется что я прав.
Ответ написан
FrostMoon
@FrostMoon
Сделайте так:
$conn1 = mysql_connect('localhost', 'root', '', true);
$conn2 = mysql_connect('localhost', 'root', '', true);

У вас параметр new_link по дефолту false, поэтому нового соединения не создается, а переписывается существующее. Просто дописывает true :)

Пруфы:
resource mysql_connect ([ string $server = ini_get(«mysql.default_host») [, string $username = ini_get(«mysql.default_user») [, string $password = ini_get(«mysql.default_password») [, bool $new_link = false [, int $client_flags = 0 ]]]]] )

new_link
Если второй вызов функции mysql_connect() произошёл с теми же аргументами, то новое соединение не будет установлено. Вместо этого функция вернёт ссылку на уже установленное соединение. Параметр new_link может заставить функцию mysql_connect() открыть ещё одно соединение, даже если соединение с аналогичными параметрами уже открыто. В SQL safe mode этот параметр игнорируется.
Ответ написан
Комментировать
@DorBer
У mysql_connect используйте четвертый параметр:

resource mysql_connect ([ string $server = ini_get(«mysql.default_host») [, string $username = ini_get(«mysql.default_user») [, string $password = ini_get(«mysql.default_password») [, bool $new_link = false [, int $client_flags = 0 ]]]]] )
Ответ написан
Anton_from_Amber
@Anton_from_Amber
Сталкивался с такой штукой. Решается применением различных хостов при подключении. К примеру у вас есть мастер и реплика на одной машине. Укажите в DNS: ms.domain.com A 192.168.0.1, rp1.domain.com A 192.168.0.1 Используйте эти два различных доменных имени для установки различных соединений. Можно использовать доменное имя, ip-адрес и псевдонимы типа localhost, если у вас нет доступа к DNS.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы