Edit report at http://bugs.php.net/bug.php?id=44454&edit=1

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

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] 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.. ;)

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

Correction:



 emulated prepared statements - not using traversable - Issue exists

 emulated prepared statement  -     using traversable - Issue exists



------------------------------------------------------------------------
[2008-07-03 16:37:49] u...@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

Reply via email to