Jump to content
  • 0

mysql_query с link_identifer


homm
 Share

Question

Здавствуйте.

Для запросов к базе пишу обертку (такой велосипедик).

Придумал link_identifer засовывать в статическое поле, кому нужно тот проинициализирует, кому не надо, не будет о нем подозревать. Беда в том, что при любом значении по умолчанию для link_identifer, mysql_query не хочет отрабатывать. Поэтому сейчас приходится делать так:

function __construct($sql){
if (cDBQuery::$link){
$this->r = mysql_query($sql, cDBQuery::$link);
if (mysql_errno(cDBQuery::$link)){
throw new Exception("cDBQuery->__construct() : ".mysql_error(cDBQuery::$link));
}
} else {
$this->r = mysql_query($sql);
if (mysql_errno()){
throw new Exception("cDBQuery->__construct() : ".mysql_error());
}
}
}
static public $link = NULL;

Хочется что-бы это выглядело вот так:

function __construct($sql){
$this->r = mysql_query($sql, cDBQuery::$link);
if (mysql_errno(cDBQuery::$link)){
throw new Exception("cDBQuery->__construct() : ".mysql_error(cDBQuery::$link));
}
}
static public $link = ???; // чем проинициализировать?

Если так нельзя, то как получить идентификатор по умолчанию, который использует mysql_query, когда тот не задан явно?

Link to comment
Share on other sites

8 answers to this question

Recommended Posts

  • 0
mysql_query() посылает запрос активной базе данных сервера, на который ссылается переданный указатель. Если параметр link_identifier опущен, используется последнее открытое соединение. Если открытые соединения отсутствуют, функция пытается соединиться с СУБД, аналогично функции mysql_connect() без параметров. Результат запроса буфферизируется.

кстати в мануале (в разделе Классы и Объекты) есть очень полезный пример организации класса взаимодействия с MySQL

Как вариант

class MySQLQuery {
private $host, $login, $pass, $baza;
static public $link;
public $result;
public function __construct ($h, $l, $p, $b) {
$this->host = $h;
$this->login = $l;
$this->pass = $p;
$this->baza = $b;
$this->connect();
}
private function connect() {
$this->link = mysql_connect(); //с параметрами, с дополнительными директивами.
}
public function muskulQuery($sql) {
$this->result = mysql_query($sql, self::$link);
if (mysql_errno(self::$link))
throw new Exception("MySQLQuery->muskulQuery() : ".mysql_error(self::$link));
}
}
$MyQuery = new MySQLQuery('','','','');
$MyQuery->muskulQuery($sql);
$r = $MyQuery->result;;

Link to comment
Share on other sites

  • 0

Yarik Voronov, ты немножко не понял.

В задачи класса не входит подключение к базе данных, только работа с запросами, соответственно узнать идентификатор негде. Но хочется иметь возможеость что-бы он все-же торчал наружу, и если кому-то захочется работать с другим идентичикатором, была такая возможность.

Сейчас для определения указан или нет идентификатор использую ветвления, а хочется просто передать

mysql_query($sql, cDBQuery::$link); и пусть уже mysql_query сама думает, задан идентификатор или использовать по умолчанию. Беда в том, что когда я делаю mysql_query($sql, NULL), она считает что параметр соединения задан, но задан не верно.

Меня интерисует возможность посылать второй параметр всегда, для исключения ветвления. Т.к. функция не переваривает пустые параметры, может тогда можно узнать соединение по умолчанию? Где-то же она его берет.

Link to comment
Share on other sites

  • 0
Yarik Voronov, ты немножко не понял.

В задачи класса не входит подключение к базе данных, только работа с запросами, соответственно узнать идентификатор негде. Но хочется иметь возможеость что-бы он все-же торчал наружу, и если кому-то захочется работать с другим идентификатором, была такая возможность.

Я уж не знаю какой другой идентификатор может торчать наружу в процессе выполнения один запрос - один экземпляр скрипта - один (уникальный) идентификатор соединения. тем более не понимаю как может захотеться пользователю работать с другим идентификатором. если он (пользователь) все-таки сам захочет и более того сможет поработать с другим идентификатором то, он не совсем обычный пользователь... так вот, если использована функция mysql_connect() то:

Соединение с сервером будет закрыто при завершении исполнения скрипта, если до этого оно не будет закрыто с помощью функции mysql_close().

и если прочитать еще раз мануал то

mysql_query() посылает запрос активной базе данных сервера, на который ссылается переданный указатель. Если параметр link_identifier опущен, используется последнее открытое соединение.

т.о. неважно было ли оно открыто в классе или в функции - mysql_query() "отыщет этот указатель" - если коннект был сделан.

Сейчас для определения указан или нет идентификатор использую ветвления, а хочется просто передать mysql_query($sql, cDBQuery::$link); и пусть уже mysql_query сама думает, задан идентификатор или использовать по умолчанию. Беда в том, что когда я делаю mysql_query($sql, NULL), она считает что параметр соединения задан, но задан не верно.

Есстественно ибо думать mysql_query за программиста не может по прототипу.

Меня интерисует возможность посылать второй параметр всегда, для исключения ветвления. Т.к. функция не переваривает пустые параметры, может тогда можно узнать соединение по умолчанию? Где-то же она его берет.

так же в мануле сказано

mysql_connect() устанавливает соединение с сервером MySQL. Следующие значения по умолчанию установлены для отсутствующих параметров: server = 'localhost:3306', username = имя пользователя владельца процесса сервера и password = пустой пароль.

если это не было переопрнделено в php.ini

Так вот если все же прочесть мануал (намек) то можно утверждать следующее: что раз идентификатор не указан при запросе, то и запрос выполнять не следует, потому что с умолчателыми параметрами не проконнектиться

function __construct($sql){
if (cDBQuery::$link!=NULL) { // false, undefined, 0 - это уже самому решать
$this->r = mysql_query($sql, cDBQuery::$link);
if (mysql_errno(cDBQuery::$link)) throw new Exception("cDBQuery->__construct() : ".mysql_error(cDBQuery::$link));
}
}

либо менять cDBQuery::$link в зависимости от того кто пришел. для админа скажем одно соедениение (пользователь пароль права доступа и т.д.), для обычного пользователя другое (права на туже базу но USAGE), для черного списка вообще доступ закрыт (то есть link = NULL, соединение вообще не устанавливалось)

ЗЫ следует учитывать что

Если второй вызов функции произош?л с теми же аргументами mysql_connect(), новое соединение не будет установлено. Вместо этого функция верн?т ссылку на уже установленное соединение. Параметр new_link может заставить функцию mysql_connect() открыть ещ? одно соединение, даже если соединение с аналогичными параметрами уже открыто.
Link to comment
Share on other sites

  • 0
Я уж не знаю какой другой идентификатор может торчать наружу в процессе выполнения один запрос - один экземпляр скрипта - один (уникальный) идентификатор соединения.

Ты не путаешь результат запроса и идентификатор соединения? Вообще-то один запрос можно сделать с любым открытым соединением.

Меня интерисует возможность посылать второй параметр всегда, для исключения ветвления. Т.к. функция не переваривает пустые параметры, может тогда можно узнать соединение по умолчанию? Где-то же она его берет.

так же в мануле сказано

Ты опять не понял, ?соединение по умолчанию?, это не то, что устанавливается, когда подключений нет, это последнее открытое соединение, которое mysql_query использует в случае когда идентификатор не задан.

Так вот если все же прочесть мануал (намек) то можно утверждать следующее: что раз идентификатор не указан при запросе, то и запрос выполнять не следует, потому что с умолчателыми параметрами не проконнектиться

Блин!!! Класс не решает вопросы коннекта, коннект делается пользователем до работы с классом любым удобным способом. Но коннектов может быть сделано 2, 4, 50 к разным серверам, и нужно иметь возможность указать какой коннект использовать для работы с классом, а если явно не указано, работать с соединением ?по умолчанию?, тем, которое ?последнее открытое соединение?.

if (cDBQuery::$link!=NULL) {

Это в корне не верно. То, что link не задаен значит лишь то, что его не задал пользователь, а не то, что коннекта к базе нет.

т.о. неважно было ли оно открыто в классе или в функции - mysql_query() "отыщет этот указатель" - если коннект был сделан.

Я знаю, я об этом в первом посте написал. Ну попробуй почитать уже прежде чем писать, я заколебался одно и то-же уже жувать.

Link to comment
Share on other sites

  • 0

Так. что-то мы недопонимаем друг-друга.

Запрос и идентафикатор я не путаю. Прошу прощения не ясно выразился. Здесь подразумевается запроc на HTTP-сервер от браузера. Т.е. у меня открыто окно добавления поста - нажав отправить, я посылаю запрос. Сервер приняв запрос направляет его скрипту. скрипт (множество инклудов - это один скрипт) обрабатыевает полученные данные. так как я залогинился, то устанавливается соединение (канал) с мускулом, происходит множество запросов (допустим) к MYSQL по этому каналу, пишется в базу инфа, выдается подтверждение что инфа принята успешно. и все конект (канал связи) с мускулом отрубается - скрипт закончился.

Я же получил уведомление... и вот тут получается самое интересное - происходит редирект на другую страницу, а это уже новый запрос - новый экземпляр другого скрипта - новый идентификатор связи с базой. и эта цепочка HTTP-запрос - экземпляр скрипта - новый идентификатор будет повторяться всегда даже если я решу отставить 1000 постов и каждый раз я буду получать новый идентификатор соединения с одной и той же базой. то есть в РНР-переменной с одним и тем же именем у меня будет каждый раз новое значение идентификатора соединения.

так вот я пока не понимаю как это

коннект делается пользователем до работы с классом любым удобным способом

потому что конект делается в скрипте (и вполне однозначным способом) при обработке запроса от браузера. и соединение должно быть открыто каждый раз при каждом новом HTTP-запросе от браузера.

поэтому если пользователю (в браузере) предлагается сделать коннект на выбор из списка, то этот выбор следует запомнить (в cookies, sessions) и потом использовать не открытое когда-либо соединение при к-л другом HTTP-запросе, потому что "старого" соединения не будет при использовании mysql_connect(), а параметры для создания этого соединения (этих соединений). я пока намеренно молчу про mysql_pconnect() чтобы не запутывать.

если же я в скрипте открою до выполнения основной обработки 100 соединений с разными базами с разными серверами и подам запрос к MуSQL без идентификатора, то будет использовано 100-е соединение. более того все 100 соединений закроются когда закончиться скрипт. и кстати все использованные PHP переменные уничтожаться в оперативной памяти сервера. посему я не вижу смысла открывать 100 соединений и еще к тому же не знать к какому из 100 надо обратиться, чтобы выполнить MySQL-запрос. если же я знаю к какому соединению надо обратиться (какое соединение создать), то нах... мне открывать все 100? (это риторическое размышление). Из предидущего абзаца: если пользователь не указал никакого конкретного соединения, то я однозначно знаю, что надо использовать параметры для открытия соединения, решенного мною (или ранее пользователем) быть default.

если же пользователем указаны 50-разных соединений, то я точно должен знать на каком MySQL-сервере данный конкретный запрос может быть выполнен: если на всех 50 то cDBQuery::$link - это массив, если только на 20, то должна быть привязка (или правильная обработка ошибок).

Link to comment
Share on other sites

  • 0

Ну и зачем блин все эти понятные с 3-го класса вещи писать? Если не так не видно, что я разбираюсь как работает веб, могу сказать прямо: я разбираюсь как работает веб.

посему я не вижу смысла открывать 100 соединений

С этого бы и начал. Давай объясню: каждое соединение может быть к отдельному серверу со своими уникальными базами данных и свомими уникальными данными, и все они могут быть нужны. В этом случае пользователь (пользователь моего класса, не путай) конечто хранит все 100 соединений где-то у себя, и знает для чего какое нужно. В этом случае, что-бы обратится к конкретному соединению он присвоит

cDBQuery::$link = $my_link;

Но есть и другоой случай, когда пользователь (пользователь моего класса, не путай) просто делает mysql_connect и ему наплевать на возвращенный идентиыикатор, т.к. у него одно соединение и все функции будут работать и так.

Класс должен работать в обоих случаях. Сейчас это делается с помошью ветвления. (см первый пост) а я хочу передавать в mysql_query какой-то идентификатор соединения что-бы она работала так как будто ей не предавали идентификатора и она выбирала последнее соединение. Это можно сделать 2-мя способами:

1) Передать какое-то значение, которое бы сказал ?нет идентификатора?. Обычно подходит NUL или даже 0, но в данном случае mysql_query упрамится, говорит что иденификатор не верный.

2) Самому заранее узнать последний идентификатор соединения, и передать его явно.

Я пишу одно и то-же третий раз. Пожалей меня, прочти хоть теперь, а?

Link to comment
Share on other sites

  • 0
Я пишу одно и то-же третий раз. Пожалей меня, прочти хоть теперь, а?

1. Не пожалею.

2. ты пишешь не одно и то же.

3. вразумительная задача поставлена впервый раз

4. я задолбался переписывать манул в пост.

6. пользователь не может хранить у себя 100 соединений, он может хранить у себя только параметры чтобы сделать эти 100 соединений ч/з серверный скрипт, написаный тобой.

7. пользователь не может хранить у себя локально идентификаторы 100 соединений от одного HTTP-запроса к другому HTTP-запросу, т. к. все 100 соединений закроются когда закончиться скрипт.

8. mysql_query() не может правильно работать если параметр link_identifer передан как NULL | FALSE | 0

9. соединение должно быть открыто при каждом новом конкретном HTTP-запросе.

Т.о. при каждом конкретном HTTP-запросе уже известно каким должно быть значение cDBQuery::$link = $my_link; Посяму? потому что согласно пп 6,7,9 $my_link получает значение всегда и только всегда в серверном скрипте написаном тобой и:

5. прочти внимательно последние два абзаца пердидущего моего поста

5.1. ибо "если же пользователем указаны" - понятие максимально растяжимое. это могут быть параметры профиля пользователя заданные при регистрации, это могут быть параметры сохраненные в профиле с последнего сеанса, это могут быть параметры заданные пользователем через форму в этом сеансе, это могут быть параметры указанные пользователем как default, это могут быть параметры заданные тобой как default если пользователь их не создал или не задал, это могут быть параметры привязанные к конкретной ситуации выраженной в HTML странице, в конце концов это могут быть параметры сохраненные на сервере от предидущего HTTP-запроса в этом сеансе

10. Итого: если cDBQuery::$link == NULL, то значит MySQL запрос делать не надо! ибо см п.9

Всего: вопрос должен ставиться так: "Как определить с какими параметрами должно быть сделано соединение?" А это вопрос алгоритма, разъясненный в п. 5.1

ЗЫ: Если же было открыто 50 соединений, то cDBQuery::$link всегда будет указывать на последнее (если cDBQuery::$link не есть массив, если массив - то последный елемент массива и есть последнее открытое сооединение)

ЗЗЫ: если позарез нужно передавать ОДНО соединение от одного HTTP-запроса к другому HTTP-запросу

то следует использовать mysql_pconnect(). и хранить его идентификатор в сессии.

Link to comment
Share on other sites

  • 0

Суммируя все разяснения даю свой короткий, полный и вразумительный ответ:

Всегда присваивать cDBQuery::$link идентификатор на открытый канал связи с MySQL. а уж как, какой, и по какому принципу ты откроешь канал связи - это твои заботы :)

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. See more about our Guidelines and Privacy Policy