Edit report at http://bugs.php.net/bug.php?id=44454&edit=1
ID: 44454 Comment by: rgagnon24 at gmail dot com Reported by: mfisc...@php.net Summary: Unexpected exception thrown in foreach() statement Status: Verified Type: Bug Package: PDO related Operating System: * PHP Version: 5.*, 6CVS (2009-04-25) New Comment: From: http://dev.mysql.com/doc/refman/5.0/en/mysql-errno.html "Note that some functions like mysql_fetch_row() don't set mysql_errno() if they succeed." And: http://dev.mysql.com/doc/refman/5.0/en/mysql-fetch-row.html "Note that error is not reset between calls to mysql_fetch_row()" ----------------------------------------------------------------------------- Since all the SELECT'd rows are fetched ok, the error from the botched insert is still hanging around for mysql_errno() to find, and raise the exact same exception after the data is finished being iterated. Previous Comments: ------------------------------------------------------------------------ [2010-06-03 20:03:37] rgagnon24 at gmail dot com Looking at pdo_mysql extension source code, I see the exception is actually being raised twice, not being buffered. from php5.2.13 source, file ext/pdo_mysql/mysql_statement.c is calling _pdo_mysql_error() in two places. Once from line 218 in pdo_mysql_stmt_execute() after mysql_real_query() fails, and then again at line 425 in pdo_mysql_stmt_fetch() because mysql_errno() indicates there is an error. ------------------------------------------------------------------------ [2010-05-08 06:08:33] gregory at tiv dot net Correction: ----------- if ( $conn->errorCode() ) { should be if ( $conn->errorCode() !== '00000' ) { ------------------------------------------------------------------------ [2010-05-07 02:13:48] gregory at tiv dot net I have a simpler test case, one solution/explanation and one workaround. Tested under: Windows - PHP 5.2.13 (cli) (built: Feb 24 2010 14:32:32) FreeBSD - PHP 5.2.12 with Suhosin-Patch 0.9.7 (cli) (built: Feb 24 2010 23:12:45) Demonstration code: ------------------- <?php # # PDO foreach exception bug # Demonstration code # Author: Gregory Karpinsky, http://www.tiv.net # 2010-05-06 print '<p>This code works OK (Exception is cleaned artificially)</p>'; $conn = new PDO( 'mysql:host=localhost', 'test', 'test' ); $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $oRS = $conn->query( "select 'OK'" ); foreach ( $oRS as $row ) { try { $conn->query( 'Bogus SQL' ); } catch (PDOException $e) {} if ( $conn->errorCode() ) { $conn->query( "select 'CLEAN_PDO_ERROR'" ); } print '<p>NO exception will be thrown.</p>'; } print '<p>This code works OK (two separate connections)</p>'; $conn = new PDO( 'mysql:host=localhost', 'test', 'test' ); $conn2 = new PDO( 'mysql:host=localhost', 'test', 'test' ); $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $conn2->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $oRS = $conn->query( "select 'OK'" ); foreach ( $oRS as $row ) { try { $conn2->query( 'Bogus SQL' ); } catch (PDOException $e) {} print '<p>NO exception will be thrown.</p>'; } print '<p>This code throws unexpected exception in foreach</p>'; $conn = new PDO( 'mysql:host=localhost', 'test', 'test' ); $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $oRS = $conn->query( "select 'OK'" ); foreach ( $oRS as $row ) { try { $conn->query( 'Bogus SQL' ); } catch (PDOException $e) {} print '<p>Exception will be thrown after this...</p>'; } ?> ------------------------------------------------------------------------ [2009-04-25 17:16:14] mfisc...@php.net Using Windows snapshots, verified that the bug still exists in 5.2.10-dev and 5.3.0RC2-dev . Cannot test with 6.0.0-dev, the php.exe doesn't even properly start. ------------------------------------------------------------------------ [2009-04-25 14:57:23] j...@php.net Does this still exist? If so, update the version properly.. ;) ------------------------------------------------------------------------ The remainder of the comments for this report are too long. To view the rest of the comments, please view the bug report online at http://bugs.php.net/bug.php?id=44454 -- Edit this bug report at http://bugs.php.net/bug.php?id=44454&edit=1