Bug #44454 [Com]: Unexpected exception thrown in foreach() statement

From: Date: Sat, 08 May 2010 04:08:33 +0000
Subject: Bug #44454 [Com]: Unexpected exception thrown in foreach() statement
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-150262@lists.php.net to get a copy of this message
Edit report at http://bugs.php.net/bug.php?id=44454&edit=1

 ID:               44454
 Comment by:       gregory at tiv dot net
 Reported by:      mfischer@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:

Correction:
-----------
if ( $conn->errorCode() ) {

should be

if ( $conn->errorCode() !== '00000' ) {


Previous Comments:
------------------------------------------------------------------------
[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] mfischer@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] jani@php.net

Does this still exist? If so, update the version properly.. ;)

------------------------------------------------------------------------
[2008-07-03 16:44:39] uw@php.net

Correction:

 emulated prepared statements - not using traversable - Issue exists
 emulated prepared statement  -     using traversable - Issue exists


------------------------------------------------------------------------
[2008-07-03 16:37:49] uw@php.net

No comment on the cause just some observations. Issue exists with SQLite
as well. 

PHP 5.3 CVS

MySQL results:

 emulated prepared statements - not using traversable - OK
 emulated prepared statement  -     using traversable - Issue exists
 
 native prepared statements   - not using traversable - OK
 native prepared statements   -     using traversable - OK

SQLite:

 emulated prepared statements - not using traversable - Issue exists
 emulated prepared statement  -     using traversable - Issue exists



"not using traversable":

$stmt = $db->query('SELECT a, b FROM test');
while ($row = $stmt->fetch()) {
  try {
    $db->exec('INSERT INTO test(a, b) VALUES (1, 1)');
  } catch (Exception $e) {
    printf("while loop\n");
  }
}


"using traversable":

$stmt = $db->query('SELECT a, b FROM test');
foreach ($stmt as $row) {
  try {
   $db->exec('INSERT INTO test(a, b) VALUES (1, 1)');
  } catch (Exception $e) {
    printf("foreach\n");
  }
}  

------------------------------------------------------------------------


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


Thread (16 messages)

« previous php.bugs (#150262) next »