powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / PHP PDO - непонятные Exception
9 сообщений из 9, страница 1 из 1
PHP PDO - непонятные Exception
    #39114479
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть такой фрагмент:
Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
	static public function commit()
	{
		$dbh = static::dbh();
		if (!$dbh) return static::_error("Невозможно зафиксировать транзакцию, соединение не открыто");
		$ret = static::_error();
		try
		{
			$ret = $dbh->commit();
		}
		catch (PDOException $e)
		{
			static::_error($e);
			trigger_error(static::error(), E_USER_NOTICE);
			$ret = null;
		}
		return $ret;
	}


При выполнении этого кода вызывается исключение, причем с нулевым кодом ошибки ($e->getCode = 0).
Не могу понять, почему?
Вроде бы нулевой код означает отсутствие ошибок, откуда же тогда исключение?

И еще в одном месте:
Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
		try
		{
			$ret = $dbh->prepare($sql, (array)$options);
			$ret->execute((array)$params);
		}
		catch (PDOException $e)
		{
			static::_error($e);
			trigger_error(static::error(), E_USER_NOTICE);
			$ret = null;
		}


На ->execute вылетает исключение с SQLSTATE=HY093.
Текст SQL-запроса ошибок не содержит:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
insert into `SESSION` (`SESSION`, `KEY`, `STATUS`, `USERNAME`, `DOMAIN`, `REALM`, `SOURCE`, `IP`, `UA`, `HDR`, `STARTED`, `EXPIRED`, `REASON`)
values                (:session , :key , :status , :username , :domain , :realm , :source , :ip , :ua , :hdr , now()    , :expired , :reason )
on duplicate key update
  `SESSION` = values(`SESSION`)
, `STATUS` = values(`STATUS`)
, `USERNAME` = values(`STATUS`)
, `DOMAIN` = values(`DOMAIN`)
, `REALM` = values(`REALM`)
, `SOURCE` = values(`SOURCE`)
, `IP` = values(`IP`)
, `UA` = values(`UA`)
, `HDR` = values(`HDR`)
, `STARTED` = now();
, `EXPIRED` = values(`EXPIRED`)
, `REASON` = values(`REASON`)


Параметры передаются как ассоциированный массив (в $params).

________________________
Мы смотрим с оптимизмом...
...в оптический прицел.
...
Рейтинг: 0 / 0
PHP PDO - непонятные Exception
    #39114528
vkle
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alibek B.Параметры передаются как ассоциированный массив (в $params).Количество и имена параметров точно соответствуют запросу?
...
Рейтинг: 0 / 0
PHP PDO - непонятные Exception
    #39114563
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да, оказалось что один параметр не передавался.
Я думал, что PDO тогда им null назначает. Исправил.
Исключение с кодом 0 на commit в описании ссылается на то, что нет действующей транзакции, хотя я ее начинал. Как исправить пока не понял.
...
Рейтинг: 0 / 0
PHP PDO - непонятные Exception
    #39116359
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
С Exception тоже разобрался.
Но в ситуации не разберусь.

У меня выполняется SQL-запрос с INSERT.
Выполняется успешно, судя по коду возврата.
Однако в БД строка не появляется.

Вот фрагмент кода:
Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
		try
		{
			$ret = $dbh->prepare($sql, (array)$options);
			$rc = $ret->execute($params);
		}
		catch (PDOException $e)
		{
			static::_error($e);
			trigger_error(static::error(), E_USER_NOTICE);
			$ret = null;
		}
		if (static::debug())
		{
			print "\n*DEBUG*\n";
			print "Return code: $rc\n";
			if (isset($ret)) $ret->debugDumpParams();
			print_r($params);
			print "\n";
		}



вот отладочный вывод с этого кода:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
*DEBUG*
Return code: 1
SQL: [658] insert into `SESSION` (`SESSION`, `KEY`, `STATUS`, `USERNAME`, `DOMAIN`, `REALM`, `SOURCE`, `IP`, `UA`, `HDR`, `STARTED`, `EXPIRED`, `REASON`)
values                (:session , :key , :status , :username , :domain , :realm , :source , :ip , :ua , :hdr , now()    , :expired , :reason )
on duplicate key update
  `SESSION` = values(`SESSION`)
, `STATUS` = values(`STATUS`)
, `USERNAME` = values(`STATUS`)
, `DOMAIN` = values(`DOMAIN`)
, `REALM` = values(`REALM`)
, `SOURCE` = values(`SOURCE`)
Params:  12
Key: Name: [8] :session
paramno=-1
name=[8] ":session"
is_param=1
param_type=2
...
Array
(
    [session] => sb6hces66bgq85ulhp6uhpo4sgi7imffbnn3pg1qc3dcbenfft01
    [username] => username1
    [domain] => 
    [realm] => 
    [source] => webportal
    [ip] => 1.2.3.4
    [ua] => Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.86 Safari/537.36
    [hdr] => 
    [key] => 3066e72aa8c21918d768869d7271aa5f86cc87f8749519446b0a1df2562014a3
    [status] => active
    [expired] => 
    [reason] => 
)

SQL-запрос корректный. Параметры заданы. PDOStatement создался нормально и возвращает true, то есть запрос выполнился успешно.
Но в БД почему-то пусто.
...
Рейтинг: 0 / 0
PHP PDO - непонятные Exception
    #39116486
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Разобрался.
Нужно было делать closeCursor.
...
Рейтинг: 0 / 0
PHP PDO - непонятные Exception
    #39116724
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Подскажите, как правильно сделать.

Есть класс-обертка для работы с БД через PDO.
Упрощенно он примерно такой:
Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
function query($sql, $params=null, $options=null)
{
	$dbh = $this->dbh();
	$rc = null;
	try
	{
		$ret = $dbh->prepare($sql, (array)$options);
		$rc = $ret->execute($params);
	}
	catch (PDOException $e)
	{
		trigger_error($e, E_USER_NOTICE);
		$ret = null;
	}
	return $ret;
}



Здесь метод query подготавливает и выполняет запрос, а затем возвращает его.
Вызывающий код с этим подготовленным запросом делает что-нибудь: получает атрибуты, фетчит данные. Или ничего не делает, если это не select-запрос (а, например, insert или delete).
В вызывающем коде этот метод используется например так:
Код: php
1.
2.
3.
$db->begin();
$db->query("insert into table values (?, ?, ?)", array(1,2,3));
$db->commit();



Но вот именно этот код работать не будет.
В данном коде из-за незакрытого курсора не отрабатывает commit и изменения откатываются.
Но при этом не вызывается исключение (что ИМХО баг PDO), поэтому проблему сразу и не понять.
Нужно делать так:
Код: php
1.
2.
3.
4.
$db->begin();
$ret = $db->query("insert into table values (?, ?, ?)", array(1,2,3));
$ret->closeCursor();
$db->commit();


или
Код: php
1.
2.
3.
$db->begin();
$db->query("insert into table values (?, ?, ?)", array(1,2,3))->closeCursor();
$db->commit();


или
Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
class DB {
function query($sql, $params=null, $options=null, $close=true)
{
	$dbh = $this->dbh();
...
		$ret = $dbh->prepare($sql, (array)$options);
		$rc = $ret->execute($params);
		if ($close) $ret->closeCursor();
...
}
}
...
$db->begin();
$db->query("insert into table values (?, ?, ?)", array(1,2,3), null, true);
$db->commit();



Но как-то это коряво.
А как это сделать кошерно?
...
Рейтинг: 0 / 0
PHP PDO - непонятные Exception
    #39116808
SharuPoNemnogu
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пишут что closeCursor для fetch был сделан, если не все запили прочитали, а надо выполнить другой запрос. А если транзакцию обернуть в try catch ничего не выкинет?
Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
$dbh->beginTransaction();

try {
     // insert/update query

     $dbh->commit();
} catch (Exception $e) {
     $dbh->rollBack();
     //...
}
...
Рейтинг: 0 / 0
PHP PDO - непонятные Exception
    #39116816
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У меня так и сделано, транзакция внутри try.
Она вроде бы успешно применяется (метод возвращает true, мои сообщения выше), но по факту откатывается, поскольку строки в БД не добавляются.
Стал закрывать курсор перед commit - и все заработало.
...
Рейтинг: 0 / 0
PHP PDO - непонятные Exception
    #39116866
SharuPoNemnogu
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
тогда лучше флаг в параметрах функции. Через пару лет хоть понятно будет что это и зачем (если снабдить еще комментарием, вообще кошерно).
...
Рейтинг: 0 / 0
9 сообщений из 9, страница 1 из 1
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / PHP PDO - непонятные Exception
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]