Эта тема на forum.dklab.ru


Педагог: Открытие двух БД и возврат
Здравствуйте.
Вот такая проблемка. В php-скрипте есть постоянное соединение к какой-то БД. Но в одном месте нужно подключиться временно к другой БД взять оттуда данные, и вернуться к основной БД. Приведу код:
$dbh=mysql_connect('localhost','login1','password1');
mysql_select_db('database1');
mysql_query('select * from t where id=1');
func();
mysql_query('select * from t where id=2');

function func()
{
// вот тут бы узнать текущую db
$cur_db_name=имя_текущей_открытой_бд();
$cur_db_link=линк_на_текущую_открытую_бд();

$dbtemp=mysql_connect('localhost','login2','password2');
mysql('database2','select * from table1',$dbtemp);
mysql_close();

// а тут бы вернуться к бд
mysql_select_db($cur_db_name,$cur_db_link);
}
Может кто подскажет эти функции (в мануале mysql искал, не нашел) или механизм такого вот возврата. Сразу замечу, что функция func() типа библиотечная, и она знать не знает, какая бд была открыта до ее вызова (в реальности могут быть до нее открыты разные бд).
MVH:
Если я правильно понял, то решается это так:
<?php
$mysql = mysql_connect(DB_HOST, DB_USER, DB_PASSWD);
mysql_select_db(DB_NAME, $mysql);
mysql_query("");
function func()
{
$mysql2 = mysql_connect(DB_HOST, DB_USER, DB_PASSWD, 1);
mysql_select_db('url_checker', $mysql2);
mysql_query("");
mysql_close($mysql2);
}
func();
mysql_query("", $mysql);
mysql_close($mysql);
?>
Т.е. открываем одно соединение, делаем запросы. Затем открываем другое с new_link = true, работаем со вторым соединением, закрываем и продолжаем работать с первым, только теперь уже обязательно надо указывать link_identified (второй аргумент) у mysql_query("", $mysql).
chin:
Ну, это только если один или два раза в работе возникает надобность в таком. А уж если это нужно на протяжении всей работы, а работа большая, то советую для этого использовать ООП.
Я сейчас работаю над сайтом онлайновой игры и там скрипту нужно работать сразу с двумя базами данных - игры и сайта. Долго мучаясь я думал, как же оптимизировать и упростить работу с данной задачей. Потом просто пришел к выводу, что тут без классов не обойтись. Теперь у меня все очень просто - два объекта: game и website. С каждым из них работа идет независимо.
Дмитрий Котеров:
Можно еще первое переоткрыть (т.е. закрыть и открыть заново).
Умолчательно соединение - то, которое открыто в скрипте последним.
Педагог:
Все ваши идеи понятны, но не решают проблему. Попробую еще разъяснить. Жил был скрипт (реально скриптЫ), работал, есть не просил:
$dbh=mysql_connect('localhost','login1','password1');
mysql_select_db('database1');
mysql_query('select * from t where id=1');
mysql_query('select * from t where id=2');
// ... и еще с десяток запросов.
И тут между первым и вторым запросом надо позарез вставить функцию func (код которой подключается через require), которая временно подключается к какой-то другой БД. То есть хотелось бы, чтобы в исходном скрипте надо было добавить только две строчки (require 'func.lib.php'; и func();) и все. Следовательно функция func() перед своей основной работой должна самостоятельно узнать link к текущей БД и имя текущей БД, чтобы после выполнения своей работы восстановить подключение.
--------------------------------
Теперь, что я накопал. Название БД можно узнать через запрос SHOW PROCESSLIST. А вот текущий линк я нашел в phpinfo() в разделе "MySQL" в поле "Active Links" (наверное это он). Только я не знаю как достать эту переменную в PHP. Подскажите плз.
Maus:
Педагог
не могу понять Вашу проблему.
зачем Вам знать текущий линк?
Что мешает Вам написать func()так ,как предложил MVH? И не трогать существующий код - явное указание resource_id будет только в func()?
Кстати, если (упрощённо) логин1==логин2 и password1==password2, то можно ничего не открывать, а просто делать запрос
SELECT col1,col2 FROM db2.table1 ....
без всяких дополнительных соединений....
Дмитрий Котеров:
не трогать существующий код - явное указание resource_id будет только в func()?
Не получится так, насколько я понимаю, потому что следующий mysql_connect() сменит текущий ID соединения на открытый, и после возврата будет бяка.

Педагог, вполне вероятно, что Ваша задача не имеет решения, ибо использованный пароль подключения к базе узнать нельзя. Однако попробуйте все же вставить в func() mysql_connect() ... mysql_close() - вдруг после закрытия соединения текущий линк восстанавливается назад... Вдруг там стек текущих линков организован...
Педагог:
Может бредовая идея, но: "А нельзя выполнить функцию func() в некоем другом процессе, который при выполнении не затрагивал ни как текущий процесс?"
Дмитрий Котеров:
Можно, но придется делать fork - в PHP это поддерживается, но я, честно говоря, не пробовал. В тому же это может тормозить (не обязательно будет, надо проверять, но — может).
Педагог:
Ну вот более ли мение решение этой проблемы:
require 'connect.lib.php'; // подключаемся к главной БД
mysql_query('select * from t where id=1'); // работаем с главной БД
func();
mysql_query('select * from t where id=2'); // работаем с главной БД
mysql_query('select * from t where id=3'); // работаем с главной БД

function func()
{
connect2db('login2','password2','db2'); // подключаемся к другой БД
mysql_query('select * from table1'); // работаем с этой другой БД
connect2db(); //восстанавливаем подключение к главной БД
}
// Файл connect.lib.php
if (!function_exists("connect2db"))
{
function connect2db($user="login",$psw="password",$db="main_database")
{
$dbh=mysql_connect ("localhost",$user,$psw) or die ('Не могу!');
mysql_select_db ($db);
return $dbh;
}
connect2db();
}

Критика принимается.
Graymur:
Лучше не мучаться и написать небольшой класс для работы с БД.
Педагог:
Graymur
Если бы проект находился на стадии разработки, то можно было бы сделать, как Вы советуете. Но перелопачивать десятки скриптов на готовом проекте не хочется (из-за лени и из-за нарушения стабильности работы).
Выложите свой класс работы с БД в "Готовые решения" - возможно мы воспользуемся им в будующих проектах.
Дмитрий Котеров:
Кстати, насчет pcntl_fork() выше речь заходила - он отпадает, вот:

It is not possible to use the function 'pcntl_fork' when PHP is used as Apache module. You can only use pcntl_fork in CGI mode or from command-line. Using this function will result in: 'Fatal error: Call to undefined function: pcntl_fork()'

Эта тема на forum.dklab.ru