Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / PHP PDO - непонятные Exception / 9 сообщений из 9, страница 1 из 1
26.11.2015, 23:16
    #39114479
Alibek B
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
PHP PDO - непонятные Exception
Есть такой фрагмент:
Код: 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
27.11.2015, 01:06
    #39114528
vkle
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
PHP PDO - непонятные Exception
Alibek B.Параметры передаются как ассоциированный массив (в $params).Количество и имена параметров точно соответствуют запросу?
...
Рейтинг: 0 / 0
27.11.2015, 07:16
    #39114563
Alibek B
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
PHP PDO - непонятные Exception
Да, оказалось что один параметр не передавался.
Я думал, что PDO тогда им null назначает. Исправил.
Исключение с кодом 0 на commit в описании ссылается на то, что нет действующей транзакции, хотя я ее начинал. Как исправить пока не понял.
...
Рейтинг: 0 / 0
30.11.2015, 14:48
    #39116359
Alibek B
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
PHP PDO - непонятные Exception
С 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
30.11.2015, 16:05
    #39116486
Alibek B
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
PHP PDO - непонятные Exception
Разобрался.
Нужно было делать closeCursor.
...
Рейтинг: 0 / 0
30.11.2015, 19:11
    #39116724
Alibek B
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
PHP PDO - непонятные Exception
Подскажите, как правильно сделать.

Есть класс-обертка для работы с БД через 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
30.11.2015, 21:59
    #39116808
SharuPoNemnogu
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
PHP PDO - непонятные Exception
Пишут что 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
30.11.2015, 22:17
    #39116816
Alibek B
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
PHP PDO - непонятные Exception
У меня так и сделано, транзакция внутри try.
Она вроде бы успешно применяется (метод возвращает true, мои сообщения выше), но по факту откатывается, поскольку строки в БД не добавляются.
Стал закрывать курсор перед commit - и все заработало.
...
Рейтинг: 0 / 0
30.11.2015, 23:53
    #39116866
SharuPoNemnogu
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
PHP PDO - непонятные Exception
тогда лучше флаг в параметрах функции. Через пару лет хоть понятно будет что это и зачем (если снабдить еще комментарием, вообще кошерно).
...
Рейтинг: 0 / 0
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / PHP PDO - непонятные Exception / 9 сообщений из 9, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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