Форум dkLab и Denwer
Здесь общаются Web-разработчики.
Генеральный спонсор:
Хостинг «Джино»

6_DbSimple version 1.x: лаконичная работа с различными СУБД (Дмитрий Котеров, оценка: 6)
Goto page Previous  1, 2, 3, 4, 5, 6, 7, 8, 9, 10  Next
Author Message
Dreammaker
Guest





Карма: 388
   поощрить/наказать


PostPosted: Wed Sep 27, 2006 1:22 pm (написано за 5 минут 43 секунды)
   Post subject: Проблема с подключением
Reply with quote

Наверное туплю,
Code (php): скопировать код в буфер обмена
<?php
include("includes/setting_env.php");
require_once("config/constants.inc.php");
require_once("libraries/DBSimple/Mysql.php");

$dsn="mysql://".SQL_USER.":".SQL_PASSWORD."@".HOST_NAME."/".BASE_NAME;

$DB=DBSimple_Generic::connect($dsn);

$DB->seterrorhandler('databaseErrorHandler');

function databaseErrorHandler($message, $info){
        if(!error_reporting (www.php.net/error_reporting)()) return;
        echo (www.php.net/echo) "SQL Error:$message<br><pre>";
        print_r (www.php.net/print_r)($info);
        echo (www.php.net/echo) "</pre>";
        exit (www.php.net/exit)();
}
?>
но у меня при подключении библиотеки выдаёт
Code (any language): скопировать код в буфер обмена
Warning: connect(DbSimple/Mysql.php) [function.connect]: failed to open stream: No such file or directory in z:\home\***.ru\www\libraries\DBSimple\Generic.php on line 89

Fatal error: connect() [function.require]: Failed opening required 'DbSimple/Mysql.php' (include_path='.;/usr/local/php/PEAR') in z:\home\***.ru\www\libraries\DBSimple\Generic.php on line 89
Звёздочками закрыл для какого проекта делаю :)

Решается путём вызова
Code (php): скопировать код в буфер обмена
require_once("libraries/DBSimple/Mysql.php");
вместо
Code (php): скопировать код в буфер обмена
require_once("libraries/DBSimple/Generic.php");
или же исправлением строки 89 в генерик
на
Code (php): скопировать код в буфер обмена
require_once str_replace (www.php.net/str_replace)('DbSimple_', '', $class) . ".php";
Второй путь натолкнул на мысль, что, возможно, что-то не так делаю, а первый вроде идеологически неправильный - идёт привязка к MySQL (пусть сейчас и она одна только и поддерживается).

Кто более умный подскажите, рлиз, где собака порылась.. :)
Back to top
Dremmaker
Guest





Карма: 388
   поощрить/наказать


PostPosted: Wed Sep 27, 2006 1:27 pm (спустя 4 минуты; написано за 1 минуту)
   Post subject:
Reply with quote

в первом коде естественно нужно для показа ошибки require_once("libraries/DBSimple/Generic.php");
Это я уже копировал с работающего с mysql.php
Back to top
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 413
   поощрить/наказать


PostPosted: Thu Sep 28, 2006 2:04 pm (спустя 1 день 37 минут; написано за 31 секунду)
   Post subject:
Reply with quote

Dreammaker wrote:
Кто более умный подскажите, рлиз, где собака порылась..
Уже обсуждалось в этом топике. Вопрос не имеет отношения к библиотеке,
pear.php.net/manual/ru/standards.php
php.net/include_path
Back to top
View user's profile Send private message Send e-mail
Guest






Карма: 388
   поощрить/наказать


PostPosted: Thu Sep 28, 2006 3:18 pm (спустя 1 час 13 минут; написано за 2 минуты 36 секунд)
   Post subject:
Reply with quote

Дмитрий Котеров wrote:
Dreammaker wrote:
Кто более умный подскажите, рлиз, где собака порылась..
Уже обсуждалось в этом топике. Вопрос не имеет отношения к библиотеке,
pear.php.net/manual/ru/standards.php
php.net/include_path
вторая ссылка некорректна правильнее так вроде ua2.php.net/manual/ru/ini.core.php#ini.include-path
.

Ну это так мелочь. Я просто сразу начал использовать вторую версию, а найденный архив не содержит файла config.php как первая версии, ну и начало топика читал достаточно давно.

Спасибо за помощь. Разобрался вроде. :)
Back to top
Nadir
Guest





Карма: 388
   поощрить/наказать


PostPosted: Mon Oct 09, 2006 3:44 am (спустя 10 дней 12 часов 26 минут; написано за 1 минуту 37 секунд)
   Post subject: Последнии версии DbSimple
Reply with quote

Дмитрий вас не затруднило бы выложить последнюю версию библиотеки, у меня появилась необходимость сделать версию для SQLlite, FireBird. Может у вас есть уже наработки?
Back to top
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 413
   поощрить/наказать


PostPosted: Mon Oct 09, 2006 11:14 am (спустя 7 часов 29 минут; написано за 17 секунд)
   Post subject:
Reply with quote

Выкладываю.
[см. ниже]

Last edited by Дмитрий Котеров on Tue Oct 31, 2006 12:56 am; edited 1 time in total
Back to top
View user's profile Send private message Send e-mail
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 413
   поощрить/наказать


PostPosted: Mon Oct 09, 2006 11:17 am (спустя 3 минуты; написано за 2 минуты 45 секунд)
   Post subject:
Reply with quote

Наработки для FireBird есть только для версии 1.x.

Но повторюсь: основная проблема сейчас - это автоматизированная система тестирования, чтобы быть уверенным: при очередном изменении библиотеки ничего не сломалось. Эта система с успехом сейчас работает для библиотеки HTML_MetaForm, так что внедрение ее в DbSimple - лишь вопрос времени. Ну а как только она будет внедрена, библиотека сразу пойдет в релиз.

Вообще, хотелось бы в первую очередь сделать драйвер для PDO - она покроет вообще все БД, поддерживаемые PHP 5.1. И уж потом - для остальных БД делать.
Back to top
View user's profile Send private message Send e-mail
Rin
Участник форума



Joined: 01 Jun 2005
Posts: 515
Карма: 185
   поощрить/наказать

Location: Москва

PostPosted: Tue Oct 10, 2006 6:00 pm (спустя 1 день 6 часов 42 минуты; написано за 25 секунд)
   Post subject:
Reply with quote

Дмитрий, в DBSimple есть очень удобный placeholder ?n, который используется для деревьев.
Нужен еще один placeholder (например ?N), который бы делал так:
Code (php): скопировать код в буфер обмена
//...
return (strlen (www.php.net/strlen)($value) == 0) ? 'NULL' : $this->escape($value);
Таким образом он позволит вносить значения в текстовые поля таблицы БД, на которые поставлен уникальный ключ.
Соответственно поле в форме можно либо не заполнять, либо не должно быть дублей.
Code (php): скопировать код в буфер обмена
$DB->query('INSERT INTO document(name) VALUES(?N)', $_REQUEST['name']);
Back to top
View user's profile Send private message Send e-mail
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 413
   поощрить/наказать


PostPosted: Wed Oct 11, 2006 1:32 pm (спустя 19 часов 31 минуту; написано за 3 минуты 22 секунды)
   Post subject:
Reply with quote

Мне кажется, эта возможность слишком близка к слою Controller из MVC. А DbSimple работает скорее на уровне Model. Так что мне бы не хотелось делать поддержку данной возможности.

Placeholder ?n сделан исключительно для того, чтобы работать с внешними ключами, которые могут быть осмысленно равны NULL, но из View это значение не передать никак. С ?N ситуация обратная: во-первых, пустая строка далеко не всегда то же самое, что NULL (я вообще стараюсь по возможности избегать NULL-ов и использую их исключительно для внешних ключей). А во-вторых, вариант VALUES(?N) не очень хорош тем, что среди значений могут встретиться как те, что требуют пустую строку, так и те, что требуют NULL.
Back to top
View user's profile Send private message Send e-mail
Rin
Участник форума



Joined: 01 Jun 2005
Posts: 515
Карма: 185
   поощрить/наказать

Location: Москва

PostPosted: Wed Oct 11, 2006 2:18 pm (спустя 46 минут; написано за 22 минуты 37 секунд)
   Post subject:
Reply with quote

Давайте посмотрим на ситуацию со стороны простого пользователя, который заполняет форму.
Например, он пишет текст новости в краткое описание и в полное описание, причём поле с кратким описанием необязательно к заполнению.

Для обычного пользователя никаких NULL не существует! Для него есть только пусто и не пусто, причём 0 - это не пусто!

Наша умная программа отслеживает дубликаты и не дает пользователю добавить один и тот же текст (а вдруг кнопку submit 2 раза нажали?).

Для программной реализации такого механизма, с точки зрения программиста, мы имеем 2 поля, например, `desc_short_md5` и `desc_full_md5` типа VARCHAR(32), на которые поставлены уникальные ключи и которые могут иметь NULL.

Еще пример.
Пользователь заполняет анкету, причем поле "возраст" (тип поля INT) и "дата рождения" (тип поля DATE) не явл. обязательными к заполнению, для пользователя они пустые, но в таблице БД, при сохранении, должен быть NULL!

Я давно использую такую универсальную конструкцию для поиска "пустышек" в полях любого типа данных:
Code (SQL): скопировать код в буфер обмена
...
WHERE (`field` IS NULL OR LENGTH(`field`) == 0)
Поэтому, получается, что для обычного пользователя NULL = ''.

P.S.
Дмирий, опишите мне, пожалуйста, пример, где нужно различить NULL и пусто, как это будет выглядеть для "простого смертного". :)
Back to top
View user's profile Send private message Send e-mail
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 413
   поощрить/наказать


PostPosted: Wed Oct 11, 2006 8:31 pm (спустя 6 часов 12 минут; написано за 1 минуту 28 секунд)
   Post subject:
Reply with quote

Различать надо при конкатенации средствами SQL, например:

SELECT concat(a, b) AS c ...
Rin wrote:
а вдруг кнопку submit 2 раза нажали?
Это, опять же, надо проверять не на уровне БД, а на уровне контроллера.
Back to top
View user's profile Send private message Send e-mail
Rin
Участник форума



Joined: 01 Jun 2005
Posts: 515
Карма: 185
   поощрить/наказать

Location: Москва

PostPosted: Thu Oct 12, 2006 3:35 pm (спустя 19 часов 4 минуты; написано за 11 минут 44 секунды)
   Post subject:
Reply with quote

Дмитрий Котеров wrote:
Различать надо при конкатенации средствами SQL, например:

SELECT concat(a, b) AS c ...
Rin wrote:
а вдруг кнопку submit 2 раза нажали?
Это, опять же, надо проверять не на уровне БД, а на уровне контроллера.
А почему нельзя это сделать на уровне БД? Это удобно.
Я использую INSERT IGNORE, после которого вызываю mysql_affected_rows().
Второй вариант -- обычный INSERT с подавлением ошибки через @, после проанализировать код ошибки, чтобы вытащить id записи с дубликатом.
Можно для отлова дублей делать отдельный запрос, который даёт больше возможностей, но это не всегда нужно.

Placeholder ?N будет очень полезен при втавке данных.

Сравните:
Code (php): скопировать код в буфер обмена
$DB->query('INSERT INTO document(name) VALUES(?)', strlen (www.php.net/strlen)($_REQUEST['name']) == 0) ? null$_REQUEST['name']);
и изящный вариант с ?N:
Code (php): скопировать код в буфер обмена
$DB->query('INSERT INTO document(name) VALUES(?N)', $_REQUEST['name']);
Ваш запрос модернизируется в
Code (SQL): скопировать код в буфер обмена
SELECT concat(IFNULL(a,''), IFNULL(b,'')) AS c ...
Back to top
View user's profile Send private message Send e-mail
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 413
   поощрить/наказать


PostPosted: Thu Oct 12, 2006 6:09 pm (спустя 2 часа 33 минуты; написано за 2 минуты 49 секунд)
   Post subject:
Reply with quote

$DB->query('INSERT INTO document(name) VALUES(?N)', nullize($_REQUEST['name']));
function nullize(&$value) { ... }

Почему нельзяполагаться на проверку двойного поста средствами БД? Например, если я в форуме 2 раза напишу одно и то же сообщение в разные моменты времени, это, очевидно, не является двойным постом. Однако если я нажму 2 раза кнопку отправки, вот это - уже двойной пост (посмотрите, как сделано на данном форме: выводится "за время, пока вы писали, уже кто-то написал"; по-моему - самый лучший вариант поведения). Т.е. метод проверки двойного поста и уникальность в базе - хотя и пересецающиеся в некоторых случаях понятия, но - пересечение далеко не полное.
Back to top
View user's profile Send private message Send e-mail
Rin
Участник форума



Joined: 01 Jun 2005
Posts: 515
Карма: 185
   поощрить/наказать

Location: Москва

PostPosted: Fri Oct 13, 2006 12:08 pm (спустя 17 часов 59 минут; написано за 9 минут 8 секунд)
   Post subject:
Reply with quote

Про двойной submit согласен.
Для "деревянного" placeholder ?n можно тоже написать что-то типа nullize(), например tree_pid_escape(), но не нужно все это.
Просто хочется увидеть читабельный синтаксис и не писать лишний код.
Задача DBSimple -- облегчить труд программисту.
Думаю, что ?N и ?n примерно одинаковы, также, как intval() и floatval().
Вобщем, было бы замечательно увидеть поддержку placeholder ?N в DBSimple.
Back to top
View user's profile Send private message Send e-mail
y0prst
Участник форума



Joined: 20 May 2004
Posts: 101
Карма: 9
   поощрить/наказать

Location: Вологда

PostPosted: Fri Oct 13, 2006 1:20 pm (спустя 1 час 11 минут; написано за 3 минуты 41 секунду)
   Post subject: MySQL UPDATE: несоответствие статьи и поведения
Reply with quote

Версия библиотеки 2.0.3. Версия модуля для MySQL - 2.0.1.
Метод query() при запросе UPDATE всегда возвращает результат запроса (TRUE или FALSE), а в статье написано, что он должен возвращать количество "охваченных" строк.
Причем такое подозрение, что это было во всех предыдущих версиях, начиная с той, что в статье (там нет вызова mysql_affected_rows).
Back to top
View user's profile Send private message
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 413
   поощрить/наказать


PostPosted: Tue Oct 17, 2006 12:03 am (спустя 3 дня 10 часов 43 минуты; написано за 2 минуты 2 секунды)
   Post subject:
Reply with quote

version 2.04
- UPDATE, DELETE, REPLACE-запросы возвращают число реально измененных строк в базе.
- Улучшено определение INSERT-запросов в MySQL (возвращается last insert id), теперь без регулярных выражений.[
[в этой версии были баги, обновление ниже]

Last edited by Дмитрий Котеров on Tue Oct 31, 2006 12:57 am; edited 1 time in total
Back to top
View user's profile Send private message Send e-mail
Kupuyc
Участник форума



Joined: 31 Mar 2006
Posts: 146
Карма: 5
   поощрить/наказать


PostPosted: Fri Oct 20, 2006 3:04 pm (спустя 3 дня 15 часов 9 секунд; написано за 6 минут 14 секунд)
   Post subject:
Reply with quote

Ув. Дмитрий Котеров, первым делом хотелось бы выразить Вам благодарность за Ваш труд и за DbSimple в частности - лаконичность записи кода в области запросов возрасла в разы, что не может не вызывать радости. Второе: существуют ситуации когда используются несколько "движков" работы с БД. К примеру DbSimple и PEAR::MDB2. В свою очередь примером может быть ситуация использования PEAR::LiveUser с механизмом хранения реализуемым через MDB2 и Вашей DbSimple под запросы не относящихся к области LiveUser - некие иные цели. Существует ряд условий и ситуций когда другой движек рвет используемое совместно с DbSimple соединение и последняя при попытке выполнения каких-либо действий спотыкается на указывающем в пустоту $this->link. Быть может, в целях повышения надежности реализовать проверку (mysql_ping к примеру) на валидность хранящегося в $this->link ресурса?
Back to top
View user's profile Send private message
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 413
   поощрить/наказать


PostPosted: Fri Oct 20, 2006 11:48 pm (спустя 8 часов 44 минуты; написано за 21 секунду)
   Post subject:
Reply with quote

Не совсем понимаю, в каких ситуациях может быть разумным обрыв соединения. Можно пример?
Back to top
View user's profile Send private message Send e-mail
Kupuyc
Участник форума



Joined: 31 Mar 2006
Posts: 146
Карма: 5
   поощрить/наказать


PostPosted: Sat Oct 21, 2006 11:30 am (спустя 11 часов 41 минуту; написано за 1 минуту 22 секунды)
   Post subject:
Reply with quote

Сейчас постараюсь. К примеру имеется код:
Code (php): скопировать код в буфер обмена
        $this->MDB2  =& MDB2::singleton($dsn);
          $this->MDB2->setFetchMode(MDB2_FETCHMODE_ASSOC);

        $this->DB = DBSimple_Generic::connect($dsn);
          $this->DB->seterrorhandler('PEngineDBErrorHandler');       

        $this->LU = LiveUser::singleton($LUConfig);
        if (!$this->LU->init()) die (www.php.net/die)($this->LU->getErrors());
Если мысленно выделить три секции, то первые lдве это инициализация движков работы с БД (впрочем первую секцию можно убрать, она необязательна), а третья - инициализация PEAR::LiveUser. В методе init() происходит ряд проверок как то время истечения сессии залогиненного пользователя. Если время вышло, то вызывается MDB2::disconnect. Т.о. после третьей секции DbSimple полагает о существовании линка к базе в то время как ее нет в случае когда пользователь обновил страницу после конца сессии - море ошибок на "не ресурс". Разумеется, дело можно решить поменяв местами вторую и третью секцию, но это скорее хак (в раздел инициализации классов работы с БД помещается проверка авторизации) чем решине. к тому же нет гарантии повторения аналогичных ситуаций ниже по коду.
   Интересно, что это не ответ на поставленный Вами вопрос о разумности, скорее уточнения положения дел :).
   Offtopic: что у Вас с кармой, перманентно падает...
Back to top
View user's profile Send private message
Maus
Модератор



Joined: 29 Jun 2003
Posts: 8151
Карма: 271
   поощрить/наказать

Location: пос. Омсукчан Магаданской области

PostPosted: Sat Oct 21, 2006 2:54 pm (спустя 3 часа 24 минуты; написано за 2 минуты 6 секунд)
   Post subject:
Reply with quote

Kupuyc
Простите, что вмешиваюсь, но я не могу понять - где здесь пользователь может успеть обновить страницу?
// offtopic: был тут как-то один "обиженный" - имхо, это его забавы. И не надоело ещё, как ни странно. Может, бота посадил?
Back to top
View user's profile Send private message
Kupuyc
Участник форума



Joined: 31 Mar 2006
Posts: 146
Карма: 5
   поощрить/наказать


PostPosted: Sat Oct 21, 2006 4:32 pm (спустя 1 час 38 минут; написано за 6 минут 43 секунды)
   Post subject:
Reply with quote

Как всегда у меня - много слов, а вот смысл донести получается с трудом :).
Quote:
где здесь пользователь может успеть обновить страницу?
Человек успешно залогинился. Затем он отвлекся и время его сессии истекло (пусть это 30 минут простоя). Он возвращается и предпринимает действие приводящее к запуску вышеприведенного кода. В случае когда время сессии вышло метод $this->LU-init() рвет соединение с БД. А вот если сессия не закончилась, то никакого разрыва не происходит. Т.е. "обновление страницы" - это действие после истечения времени сессии.

P.S. Да... сессия здесь это не php-сессия, это время в состоянии "залогинился".
Back to top
View user's profile Send private message
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 413
   поощрить/наказать


PostPosted: Sat Oct 21, 2006 5:16 pm (спустя 44 минуты; написано за 2 минуты 5 секунд)
   Post subject:
Reply with quote

А зачем init() вообще рвет соединение с базой? Мне кажется, что соединение с базой - это низший слой абстракции, который никак не должен пересекаться с бизнес-логикой по работе с юзерами (в частности, понятие "залогиненный юзер" - значительно более высокоуровневое, чем "соединение с БД", и они должны быть независимыми).

И второй вопрос: если он рвет соединение для $this->MDB2, то почему Вы считаете, что это как-то отражается на соединении $this->DB? Они же полностью независимыми должны быть.
Back to top
View user's profile Send private message Send e-mail
Kupuyc
Участник форума



Joined: 31 Mar 2006
Posts: 146
Карма: 5
   поощрить/наказать


PostPosted: Sat Oct 21, 2006 5:41 pm (спустя 24 минуты; написано за 7 минут 43 секунды)
   Post subject:
Reply with quote

1) Зачем? Хороший вопрос. Вероятно он не возникал у автора PEAR::LiveUser который в методе logout() (т.к. сессия закончилась, то ее надо уничтожить т.е. по сути разлогиниться по прошествии какого-то времени) вызывает $this->disconnect() приводящий к разрыву соединения.

2) Оба механизма используют один и тот же линк к базе (и это хорошо). Дело в том, что если первым линк начал MDB2, то DbSimple не будет открывать новый и наоборот. Схожи механизмы еще и тем, что не предусматривают использования иного механизма разделяющего с ним ресурсы. Это как раз такая ситуация.

Т.о. два выхода из ситуации:
 а) для повышения надежности проверять наличие возможности выполнения операций с БД (имеющийся линк);
 б) жаловаться автору PEAR::LiveUser на ошибку дизайна.

Уж не знаю почему, но лично мне больше нравится (уж не подумайте лишнего) вариант (а). Надежность растет, все довольны. Поправьте если имеет место быть заблуждение в этом тезисе.
Back to top
View user's profile Send private message
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 413
   поощрить/наказать


PostPosted: Sat Oct 21, 2006 6:09 pm (спустя 27 минут; написано за 3 минуты 21 секунду)
   Post subject:
Reply with quote

Kupuyc wrote:
Оба механизма используют один и тот же линк к базе (и это хорошо). Дело в том, что если первым линк начал MDB2, то DbSimple не будет открывать новый и наоборот.
Вот этого я не понимаю. Потому что лично я не делал в DbSimple поддержку множественного использования линков. Вы хотите сказать, что если в скрипте сделать 2 раза подряд mysql_connect() с одинаковыми параметрами, то на самом деле откроется не 2 соединение, а 1? Что-то странно, уж больно похоже на поведение mysql_pconnect().

Вставлять на каждом шагу проверки существования соединения лично мне кажется идеологически неверным.

Вы точно уверены, что проблема именно в закрытии соединений? Не хотите провести несколько дополнительных тестов с прямым вызовом mysql_connect(), без всяких классов?

P.S.
Жаловаться автору, конечно же, надо. Но только вначале неплохо было бы посмотреть код метода LiveUser::logout() и disconnect(), чтобы убедиться, что все работает именно так, как Вы подозреваете.
Back to top
View user's profile Send private message Send e-mail
Kupuyc
Участник форума



Joined: 31 Mar 2006
Posts: 146
Карма: 5
   поощрить/наказать


PostPosted: Sat Oct 21, 2006 8:12 pm (спустя 2 часа 3 минуты; написано за 19 секунд)
   Post subject:
Reply with quote

Quote:
Вот этого я не понимаю. Потому что лично я не делал в DbSimple поддержку множественного использования линков. Вы хотите сказать, что если в скрипте сделать 2 раза подряд mysql_connect() с одинаковыми параметрами, то на самом деле откроется не 2 соединение, а 1? Что-то странно, уж больно похоже на поведение mysql_pconnect().
Да, по документации (ru.php.net/manual/ru/function.mysql-connect.php) это именно так:
Quote:
resource mysql_connect ( [string server [, string username [, string password [, bool new_link [, int client_flags]]]]] )
Если второй вызов функции произошёл с теми же аргументами mysql_connect(), новое соединение не будет установлено. Вместо этого функция вернёт ссылку на уже установленное соединение. Параметр new_link может заставить функцию mysql_connect() открыть ещё одно соединение, даже если соединение с аналогичными параметрами уже открыто.
Я старательно прошел несколько раз проблемный участок дебаггером:

LiveUser::init() (участок ответственный за установление конца сессии)
Code (php): скопировать код в буфер обмена
if ($this->getProperty('expireTime') > 0
                    && ($this->getProperty('currentLogin') + $this->getProperty('expireTime')) < $now
                ) {
                    $this->logout(false);
                    $this->_status = LIVEUSER_STATUS_EXPIRED;
                    $this->dispatcher->post($this, 'onExpired');
                // Check if maximum idle time is reached.
                }
LiveUser::logout()
Code (php): скопировать код в буфер обмена
function logout($direct = true)
    {
        $this->_status = LIVEUSER_STATUS_LOGGEDOUT;

        if ($direct) {
            // trigger event 'onLogout' as replacement for logout callback function
            $this->dispatcher->post($this, 'onLogout');
            // If there's a cookie and the session hasn't idled or expired, kill that one too...
            $this->deleteRememberCookie();
        }

        // If the session should be destroyed, do so now...
        if ($this->_options['logout']['destroy']) {
            session_unset (www.php.net/session_unset)();
            session_destroy (www.php.net/session_destroy)();
            if ($this->_options['session']['force_start']) {
                $this->_startSession();
            }
        } elseif (array_key_exists (www.php.net/array_key_exists)($this->_options['session']['varname'], $_SESSION)) {
            unset (www.php.net/unset)($_SESSION[$this->_options['session']['varname']]);
        }

        $this->disconnect();

        if ($direct) {
            // trigger event 'postLogout', can be used to do a redirect
            $this->dispatcher->post($this, 'postLogout');
        }

        return true;
    }
LiveUser::disconnect()
Code (php): скопировать код в буфер обмена
function disconnect()
    {
        if (is_a (www.php.net/is_a)($this->_auth, 'LiveUser_Auth_Common')) {
            $result = $this->_auth->disconnect();
            if ($result === false) {
                return false;
            }
            $this->_auth = null;
        }
        if (is_a (www.php.net/is_a)($this->_perm, 'LiveUser_Perm_Simple')) {
            $result = $this->_perm->disconnect();
            if ($result === false) {
                return false;
            }
            $this->_perm = null;
        }
        return true;
    }
Дисконнект в предыдущем участке кода - вызов методов дисконнекта от БД для контейнеров хранения данных. Они-то через цепочку базирующихся на MDB2 классе методов и выполняют последовательно два раза
MDB2_Driver_mysql::disconnect($force = true) (часть метода)
Code (php): скопировать код в буфер обмена
if (!$this->opened_persistent || $force) {
    @mysql_close (www.php.net/mysql_close)($this->connection);
}
Как видно, LiveUser::logout() всегда рвет соединение ввиду безусловного вызова LiveUser::disconnect().
Интересно следуещее: в сложившейся ситуации соединение рвется всегда два раза ($this->_auth->disconnect() и $this->_perm->disconnect() делают mysql_close независимо друг от друга). Если делать что-то вроде:
Code (php): скопировать код в буфер обмена
  $link1 = mysql_connect (www.php.net/mysql_connect)(DBHost, DBLogin, DBPassword);
  $link2 = mysql_connect (www.php.net/mysql_connect)(DBHost, DBLogin, DBPassword);
  $link3 = mysql_connect (www.php.net/mysql_connect)(DBHost, DBLogin, DBPassword);
то в итоге соединение физически не будет разорвано всвязи с:
Quote:
Освобождение ресурсов
В связи с наличием системы reference-counting/подсчёта ссылок, введённой в Zend-машине РНР 4, производится автоматическое определение, когда на ресурс больше нет ссылки (как в Java). Если этот так, все ресурсы, которые использовались для данного resource, освобождаются сборщиком мусора/garbage collector. Поэтому вряд ли когда-нибудь понадобится освобождать память вручную путём использования функции free_result.
Т.е. не факт, что mysql_close разорвет соединение, ее вызов лишь уменьшит счетчик ссылок на ресурс.

Чем больше думаю, тем ближе мысль, что в вызове LiveUser::disconnect() в LiveUser::logout() нет необходимости. Получаются какие-то искусственные ограничения: 1) инициализировать (LiveUser::init()) до любого самостоятельного коннекта к БД другим механизмом работы с ней 2) делать logout самым последним действием.

Хм. Такое чувство, что на этом месте можно получить по шапке: LiveUser реализует систему авторизованного доступа и уже поэтому должен заключать все в свои "объятия". Это и является ответом на сложившуюся ситуацию - "искусственные ограничения" - логические проявления сути класса. Кажется я переутомился. Прошу прощения, если я прав только в последнем абзаце :(.

P.S. А что у Вас с кармой? ;)
Back to top
View user's profile Send private message
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 413
   поощрить/наказать


PostPosted: Sun Oct 22, 2006 12:13 am (спустя 4 часа 36 секунд; написано за 2 минуты 28 секунд)
   Post subject:
Reply with quote

Kupuyc wrote:
Параметр new_link может заставить функцию mysql_connect() открыть ещё одно соединение, даже если соединение с аналогичными параметрами уже открыто.
Ну вот. Значит, надо просто поставить new_link в DbSimple:
Code (php): скопировать код в буфер обмена
        $ok = $this->link = @mysql_connect (www.php.net/mysql_connect)(
            $p['host'] . (empty (www.php.net/empty)($p['port'])? "" : ":".$p['port']),
            $p['user'],
            $p['pass'],
            true
        );
Функция mysql_pconnect() все равно (пока?) не поддерживается.
Kupuyc wrote:
В связи с наличием системы reference-counting/подсчёта ссылок, введённой в Zend-машине РНР 4, производится автоматическое определение, когда на ресурс больше нет ссылки (как в Java). Если этот так, все ресурсы, которые использовались для данного resource, освобождаются сборщиком мусора/garbage collector. Поэтому вряд ли когда-нибудь понадобится освобождать память вручную путём использования функции free_result.
Не думаю, что счетчик ссылок распространяется на mysql_close().
Впрочем, это все можно проверить экспериментальным путем.
Back to top
View user's profile Send private message Send e-mail
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 413
   поощрить/наказать


PostPosted: Sun Oct 22, 2006 12:16 am (спустя 3 минуты; написано за 29 секунд)
   Post subject:
Reply with quote

Кстати, самый первый пользовательский комментарий вот тут:
ru.php.net/manual/ru/function.mysql-close.php#69063
- как раз об этой проблеме.
Back to top
View user's profile Send private message Send e-mail
Kupuyc
Участник форума



Joined: 31 Mar 2006
Posts: 146
Карма: 5
   поощрить/наказать


PostPosted: Sun Oct 22, 2006 6:21 am (спустя 6 часов 5 минут; написано за 1 минуту 30 секунд)
   Post subject:
Reply with quote

Я, с Вашего позволения, отвечу после викенда, чтобы опять не начать снова просто действовать. А на текущий момент наибольший отклик в душе вызывает (bugs.php.net/bug.php?id=30525,):
Quote:
At best, the current situation is that if you ever have shared links,
you should never call mysql_close if you ever expect to use that
database again in your program.
Back to top
View user's profile Send private message
Kupuyc
Участник форума



Joined: 31 Mar 2006
Posts: 146
Карма: 5
   поощрить/наказать


PostPosted: Tue Oct 24, 2006 12:19 pm (спустя 2 дня 5 часов 58 минут; написано за 3 минуты 22 секунды)
   Post subject:
Reply with quote

Доброго времени суток. По вышеупомянутой "проблеме" можно с изветсной долей уверенности говорить, что не надо ничего менять. Если вызывать LiveUser::init() ДО любой работы и останавливать его ПОСЛЕ всякой работы, а также не использовать в DbSimple форсированное создание соединения, то это будет логичней и, что самое главное, экономичнее ввиду использования shared links. Проблема возникла ввиду моего непонимания сути логики класса реализующего систему прав PEAR::LiveUser, ввиду чего я приношу свои извинения за потраченное время.
Back to top
View user's profile Send private message
Nadir
Guest





Карма: 388
   поощрить/наказать


PostPosted: Thu Oct 26, 2006 8:40 am (спустя 1 день 20 часов 20 минут; написано за 4 минуты 32 секунды)
   Post subject: Ошибка!
Reply with quote

Дмитрий Котеров wrote:
version 2.04
- UPDATE, DELETE, REPLACE-запросы возвращают число реально измененных строк в базе.
- Улучшено определение INSERT-запросов в MySQL (возвращается last insert id), теперь без регулярных выражений.
Дмитрий верните старое определение INSERT запроса, то которое в версии 2.04 работает некорректно

Если вызвать INSERT перед SELECT, то всегда возвращается результат mysql_insert_id, вместо результата.

Документация PHP вот, что говорит:
Quote:
Замечание: Значение в SQL функции MySQL LAST_INSERT_ID() всегда содержит последний сгенерированный ID и не обнуляется между запросами.
Я это вылечил, только вернув старое определение INSERT через regexp.
Back to top
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 413
   поощрить/наказать


PostPosted: Thu Oct 26, 2006 10:39 am (спустя 1 час 58 минут; написано за 28 секунд)
   Post subject:
Reply with quote

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


DbSimple_2006-10-26-11-38-34.zip
 Description:

Download
 Filename:  DbSimple_2006-10-26-11-38-34.zip
 Filesize:  11.35 KB
 Downloaded:  752 Time(s)

Back to top
View user's profile Send private message Send e-mail
Гриша
Заглянувший



Joined: 26 Oct 2006
Posts: 12
Карма: 0
   поощрить/наказать


PostPosted: Thu Oct 26, 2006 9:10 pm (спустя 10 часов 30 минут; написано за 47 секунд)
   Post subject: Сил нет, ничего не понимаю, всё вроде просто...
Reply with quote

Code (any language): скопировать код в буфер обмена
таблица:
id | name
----------
1  | Тачка
2  | Пачка
3  | Водокачка
Выполняем код:
Code (php): скопировать код в буфер обмена
$id=1;
$out_fields="name";
$field_values =$DB->selectRow('SELECT ? FROM goods WHERE id=?', $out_fields, "$id");
и получаем ---

Array
(
    [name] => name
)

причём логгер показывает запрос "SELECT 'name' FROM goods WHERE id='1'"

на этой же таблице выполняем
Code (php): скопировать код в буфер обмена
$field_values =$DB->selectRow('SELECT * FROM goods WHERE id=?', "$id");
получаем

Array
(
    [name] => Тачка
)

Мускул 4.1.16-max, PHP 4.4.2
комплект DBSimple взят отсюда меньше недели назад :)
Back to top
View user's profile Send private message
Nadir
Guest





Карма: 388
   поощрить/наказать


PostPosted: Thu Oct 26, 2006 9:15 pm (спустя 5 минут; написано за 1 минуту 31 секунду)
   Post subject: Re: Сил нет, ничего не понимаю, всё вроде просто...
Reply with quote

Гриша wrote:
Выполняем код:
Code (php): скопировать код в буфер обмена
$id=1;
$out_fields="name";
$field_values =$DB->selectRow('SELECT ? FROM goods WHERE id=?', $out_fields, "$id");
Нпиши так
Code (php): скопировать код в буфер обмена
$id=1;
$out_fields="name";
$field_values =$DB->selectRow('SELECT ?# FROM goods WHERE id=?', $out_fields, $id);
И читай доки
Back to top
Гриша
Заглянувший



Joined: 26 Oct 2006
Posts: 12
Карма: 0
   поощрить/наказать


PostPosted: Thu Oct 26, 2006 9:44 pm (спустя 28 минут; написано за 2 минуты 38 секунд)
   Post subject:
Reply with quote

Nadir
Спасибо, работает. Но и теперь я всё равно не понимаю почему.
В статье написано -
Code (any language): скопировать код в буфер обмена
я не большой знаток MySQL, допустим, что "name" это ключевое слово, но то же самое у меня было с "description" и даже с "price3" :)

а статья, на данный момент является единственным мануалом, или нет?
Back to top
View user's profile Send private message
Гриша
Заглянувший



Joined: 26 Oct 2006
Posts: 12
Карма: 0
   поощрить/наказать


PostPosted: Thu Oct 26, 2006 10:24 pm (спустя 39 минут; написано за 8 минут 52 секунды)
   Post subject:
Reply with quote

Code (php): скопировать код в буфер обмена
$out_fields_array[] = "price3";
$field_values =$DB->selectRow('SELECT ?a FROM goods WHERE id=?', $out_fields_array, "$id");
тоже не работает, вышеуказанным способом, то есть выдаёт не значение поля [price3] => 666.66, а его название [price3] => price3

SQL запрос:
SELECT 'price3' FROM goods WHERE id='1'
и почему же оно кавычки-то добавляет?

естественно, никакие
Code (php): скопировать код в буфер обмена
$field_values =$DB->selectRow('SELECT ?# FROM goods WHERE id=?', $out_fields_array, "$id");
тоже не идут, потому что ваще массив

и ещё отдельный вопрос к Дмитрию Котерову - что с версиями?
на странице посвящённой библиотеке есть ссылка "Скачать исходные коды" ведущая на файл demo.zip
на страницах форума множество всяких апдейтов, включая какую-то версию "только MySQL", которая причём и подключается судя по всему иначе...
Можно точную ссылку/страницу где говорится какие версии есть, чем отличаются и "скачать последнюю версию"

Last edited by Гриша on Thu Oct 26, 2006 10:50 pm; edited 1 time in total
Back to top
View user's profile Send private message
Гриша
Заглянувший



Joined: 26 Oct 2006
Posts: 12
Карма: 0
   поощрить/наказать


PostPosted: Thu Oct 26, 2006 10:37 pm (спустя 13 минут; написано за 3 минуты 43 секунды)
   Post subject:
Reply with quote

У меня сейчас 4 дистибутива, скачаные за последние несколько дней :))))))
Начиная с demo, который ещё подключался хитро через config.php
С ним я всё это время и игрался.
И опять же, я до сих пор не знаю - безнадёжно он устарел или аптудатен в целом?
Он по прежнему лежит на странице библиотеки и вводит в искушение незадачливых программеров :)

По моему, это смахивает на бардак... ;)

При всём моём уважении к создателю библиотеки ценность которой неоспорима и уменьшается только некоторой недодокументированностью и прочими непонятками :)
Back to top
View user's profile Send private message
Лобач Олег
Участник форума



Joined: 05 May 2003
Posts: 72
Карма: 6
   поощрить/наказать

Location: Новокузнецк

PostPosted: Fri Oct 27, 2006 4:03 am (спустя 5 часов 26 минут; написано за 1 минуту 47 секунд)
   Post subject:
Reply with quote

Гриша wrote:
SELECT 'price3' FROM goods WHERE id='1'
А Вы попробуйте этот запрос выполнить не из кода. Например, через phpMyAdmin. И раскажите что получится.
Гриша wrote:
и почему же оно кавычки-то добавляет?
Перечитайте ещё раз статью и особенно про действие плейсхолдера "?".
Back to top
View user's profile Send private message
Гриша
Заглянувший



Joined: 26 Oct 2006
Posts: 12
Карма: 0
   поощрить/наказать


PostPosted: Fri Oct 27, 2006 6:01 am (спустя 1 час 57 минут; написано за 3 минуты 14 секунд)
   Post subject:
Reply with quote

Да, понимаю, что ? в основном предназначен для вставки значений. Поэтому и ''.
Спрошу иначе - "могу ли я как нибудь вставить в запрос список полей из переменной, хоть строковой, хоть массива".
?# работает для одного поля.
Пока что я придумал типа
Code (php): скопировать код в буфер обмена
$out_fields = implode (www.php.net/implode) (", ", $out_fields_array);
$DB->selectRow('SELECT ' . $out_fields . ' FROM goods WHERE id=?', "$id")
Но как то это... некрасиво.
Back to top
View user's profile Send private message
Лобач Олег
Участник форума



Joined: 05 May 2003
Posts: 72
Карма: 6
   поощрить/наказать

Location: Новокузнецк

PostPosted: Fri Oct 27, 2006 7:15 am (спустя 1 час 14 минут; написано за 38 секунд)
   Post subject:
Reply with quote

Гриша wrote:
могу ли я как нибудь вставить в запрос список полей из переменной, хоть строковой, хоть массива
Давайте начнём с постановки задачи. Зачем Вам нужно вставлять список полей?
Back to top
View user's profile Send private message
Лобач Олег
Участник форума



Joined: 05 May 2003
Posts: 72
Карма: 6
   поощрить/наказать

Location: Новокузнецк

PostPosted: Fri Oct 27, 2006 7:23 am (спустя 7 минут; написано за 48 секунд)
   Post subject:
Reply with quote

... ну и перечитайте, на всякий случай, 4 страницу этого топика. Может там найдёте то, что вам нужно...
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   This topic is locked: you cannot edit posts or make replies. All times are GMT + 3 Hours
Goto page Previous  1, 2, 3, 4, 5, 6, 7, 8, 9, 10  Next
Page 8 of 10    Email to a Friend.
You cannot post new topics in this forum. You can reply to topics in this forum. You cannot edit your posts in this forum. You cannot delete your posts in this forum. You cannot vote in polls in this forum. You cannot attach files in this forum. You can download files in this forum.
XML