#49269 [Com]: isset() fails on Iterator object when used inside foreach declaration

2009-08-16 Thread sjoerd-php at linuxonly dot nl
 ID:   49269
 Comment by:   sjoerd-php at linuxonly dot nl
 Reported By:  president at basnetworks dot net
 Status:   Open
 Bug Type: Class/Object related
 Operating System: All
 PHP Version:  5.3.0
 New Comment:

Thank you for your bug report.

I could reproduce the behavior and made a code sample to reproduce it:

?php
class TestObject implements Iterator
{
private $first = true;
function valid()
{
if ($this-first)
{
$this-first = false;
return true;
}
return false;
}
function current() { }
function next() { }
function key() { }
function rewind() { }
}

$array_object = new TestObject();

// Without ternary operator, the foreach is entered
foreach ($array_object as $item)
{
echo This works.\n;
}

// With ternary operator, the foreach is not entered
foreach ((true ? $array_object : $array_object) as $item)
{
die(Good. Expected behavior.\n);
}
die(Bad. Foreach was skipped.\n);
?


Previous Comments:


[2009-08-16 01:36:43] president at basnetworks dot net

After further testing, I have found this bug is stranger than it
seems:

foreach ((isset($array_object) ? $array_object : array('1', '2', '3'))
as $item)
{
echo $item;
}

Should either print 'abc' or '123' no matter if isset() is successful
or fails.  It prints neither.  Now I am wondering if it is not isset(),
but the ternary operator that is failing.



[2009-08-16 01:28:52] president at basnetworks dot net

I addition to the reproduce code, the following may help to understand
the bug:

foreach ($array_object as $item)
{
echo $item;
}

Will successfully print abc, while:

foreach ((isset($array_object) ? $array_object : array()) as $item)
{
echo $item;
}

will not print anything, indicating that isset() is returning false.  I
hope that helps.



[2009-08-16 01:20:32] president at basnetworks dot net

Description:

The function isset() produces an incorrect result when used on an
object that implements the Iterator interface, within a foreach
declaration.

As illustrated below, when used outside of the foreach() declaration,
isset() works as expected in the object that implements Iterator
interface, returning true, causing the output 'true'.

When isset() is used within the foreach() declaration on the same
object, it instead returns false, causing an empty array to be used for
the foreach() loop.

There is no reason the isset() function should return anything
different when used within the foreach() declaration block.

Reproduce code:
---
class NormalClass
{
public $a, $b, $c;

public function __construct()
{
$this-a = 'a';
$this-b = 'b';
$this-c = 'c';
}
}

class ArrayClass implements Iterator
{
private $internal_array;

public function __construct()
{
$this-internal_array = array('a', 'b', 'c');
}

public function key()
{
return key($this-nodes);
}

public function current()
{
return current($this-nodes);
}

public function next()
{
next($this-nodes);
}

public function valid()
{
return (current($this-nodes) !== false) ? true : false;
}

public function rewind()
{
reset($this-nodes);
}
}

$array = array('a', 'b', 'c');
$normal_object = new NormalClass();
$array_object = new ArrayClass();

echo Array:  . (isset($array) ? 'true' : 'false');
echo \nNormal Object:  . (isset($normal_object) ? 'true' : 'false');
echo \nArray Object:  . (isset($array_object) ? 'true' : 'false');

echo \nArray: ;
foreach ((isset($array) ? $array : array()) as $item)
{
echo $item;
}

echo \nNormal Object: ;
foreach ((isset($normal_object) ? $normal_object : array()) as $item)
{
echo $item;
}

echo \nArray Object: ;
foreach ((isset($array_object) ? $array_object : array()) as $item)
{
echo $item;
}

Expected result:

Array: true
Normal Object: true
Array Object: true
Array: abc
Normal Object: abc
Array Object: abc

Actual result:
--
Array: true
Normal Object: true
Array Object: true
Array: abc
Normal Object: abc
Array Object: 





-- 
Edit this bug report at http://bugs.php.net/?id=49269edit=1



#49269 [Com]: isset() fails on Iterator object when used inside foreach declaration

2009-08-16 Thread sjoerd-php at linuxonly dot nl
 ID:   49269
 Comment by:   sjoerd-php at linuxonly dot nl
 Reported By:  president at basnetworks dot net
 Status:   Open
 Bug Type: Class/Object related
 Operating System: All
 PHP Version:  5.3.0
 New Comment:

Thank you for your bug report.

I could reproduce the behavior and made a code sample to reproduce it:

?php
class TestObject implements Iterator
{
private $first = true;
function valid()
{
if ($this-first)
{
$this-first = false;
return true;
}
return false;
}
function current() { }
function next() { }
function key() { }
function rewind() { }
}

$array_object = new TestObject();

// Without ternary operator, the foreach is entered
foreach ($array_object as $item)
{
echo This works.\n;
}

// With ternary operator, the foreach is not entered
foreach ((true ? $array_object : $array_object) as $item)
{
die(Good. Expected behavior.\n);
}
die(Bad. Foreach was skipped.\n);
?


Previous Comments:


[2009-08-16 10:52:20] sjoerd-php at linuxonly dot nl

Thank you for your bug report.

I could reproduce the behavior and made a code sample to reproduce it:

?php
class TestObject implements Iterator
{
private $first = true;
function valid()
{
if ($this-first)
{
$this-first = false;
return true;
}
return false;
}
function current() { }
function next() { }
function key() { }
function rewind() { }
}

$array_object = new TestObject();

// Without ternary operator, the foreach is entered
foreach ($array_object as $item)
{
echo This works.\n;
}

// With ternary operator, the foreach is not entered
foreach ((true ? $array_object : $array_object) as $item)
{
die(Good. Expected behavior.\n);
}
die(Bad. Foreach was skipped.\n);
?



[2009-08-16 01:36:43] president at basnetworks dot net

After further testing, I have found this bug is stranger than it
seems:

foreach ((isset($array_object) ? $array_object : array('1', '2', '3'))
as $item)
{
echo $item;
}

Should either print 'abc' or '123' no matter if isset() is successful
or fails.  It prints neither.  Now I am wondering if it is not isset(),
but the ternary operator that is failing.



[2009-08-16 01:28:52] president at basnetworks dot net

I addition to the reproduce code, the following may help to understand
the bug:

foreach ($array_object as $item)
{
echo $item;
}

Will successfully print abc, while:

foreach ((isset($array_object) ? $array_object : array()) as $item)
{
echo $item;
}

will not print anything, indicating that isset() is returning false.  I
hope that helps.



[2009-08-16 01:20:32] president at basnetworks dot net

Description:

The function isset() produces an incorrect result when used on an
object that implements the Iterator interface, within a foreach
declaration.

As illustrated below, when used outside of the foreach() declaration,
isset() works as expected in the object that implements Iterator
interface, returning true, causing the output 'true'.

When isset() is used within the foreach() declaration on the same
object, it instead returns false, causing an empty array to be used for
the foreach() loop.

There is no reason the isset() function should return anything
different when used within the foreach() declaration block.

Reproduce code:
---
class NormalClass
{
public $a, $b, $c;

public function __construct()
{
$this-a = 'a';
$this-b = 'b';
$this-c = 'c';
}
}

class ArrayClass implements Iterator
{
private $internal_array;

public function __construct()
{
$this-internal_array = array('a', 'b', 'c');
}

public function key()
{
return key($this-nodes);
}

public function current()
{
return current($this-nodes);
}

public function next()
{
next($this-nodes);
}

public function valid()
{
return (current($this-nodes) !== false) ? true : false;
}

public function rewind()
{
reset($this-nodes);
}
}

$array = array('a', 'b', 'c');
$normal_object = new NormalClass();
$array_object = new ArrayClass();

echo Array:  . (isset($array) ? 'true' : 'false');
echo \nNormal Object:  . 

#49269 [Com]: isset() fails on Iterator object when used inside foreach declaration

2009-08-16 Thread sjoerd-php at linuxonly dot nl
 ID:   49269
 Comment by:   sjoerd-php at linuxonly dot nl
 Reported By:  president at basnetworks dot net
 Status:   Open
 Bug Type: Class/Object related
 Operating System: All
 PHP Version:  5.3.0
 New Comment:

Note that the Iterator in my previous comment sucks and should not be
used.


Previous Comments:


[2009-08-16 10:53:07] sjoerd-php at linuxonly dot nl

Thank you for your bug report.

I could reproduce the behavior and made a code sample to reproduce it:

?php
class TestObject implements Iterator
{
private $first = true;
function valid()
{
if ($this-first)
{
$this-first = false;
return true;
}
return false;
}
function current() { }
function next() { }
function key() { }
function rewind() { }
}

$array_object = new TestObject();

// Without ternary operator, the foreach is entered
foreach ($array_object as $item)
{
echo This works.\n;
}

// With ternary operator, the foreach is not entered
foreach ((true ? $array_object : $array_object) as $item)
{
die(Good. Expected behavior.\n);
}
die(Bad. Foreach was skipped.\n);
?



[2009-08-16 10:52:20] sjoerd-php at linuxonly dot nl

Thank you for your bug report.

I could reproduce the behavior and made a code sample to reproduce it:

?php
class TestObject implements Iterator
{
private $first = true;
function valid()
{
if ($this-first)
{
$this-first = false;
return true;
}
return false;
}
function current() { }
function next() { }
function key() { }
function rewind() { }
}

$array_object = new TestObject();

// Without ternary operator, the foreach is entered
foreach ($array_object as $item)
{
echo This works.\n;
}

// With ternary operator, the foreach is not entered
foreach ((true ? $array_object : $array_object) as $item)
{
die(Good. Expected behavior.\n);
}
die(Bad. Foreach was skipped.\n);
?



[2009-08-16 01:36:43] president at basnetworks dot net

After further testing, I have found this bug is stranger than it
seems:

foreach ((isset($array_object) ? $array_object : array('1', '2', '3'))
as $item)
{
echo $item;
}

Should either print 'abc' or '123' no matter if isset() is successful
or fails.  It prints neither.  Now I am wondering if it is not isset(),
but the ternary operator that is failing.



[2009-08-16 01:28:52] president at basnetworks dot net

I addition to the reproduce code, the following may help to understand
the bug:

foreach ($array_object as $item)
{
echo $item;
}

Will successfully print abc, while:

foreach ((isset($array_object) ? $array_object : array()) as $item)
{
echo $item;
}

will not print anything, indicating that isset() is returning false.  I
hope that helps.



[2009-08-16 01:20:32] president at basnetworks dot net

Description:

The function isset() produces an incorrect result when used on an
object that implements the Iterator interface, within a foreach
declaration.

As illustrated below, when used outside of the foreach() declaration,
isset() works as expected in the object that implements Iterator
interface, returning true, causing the output 'true'.

When isset() is used within the foreach() declaration on the same
object, it instead returns false, causing an empty array to be used for
the foreach() loop.

There is no reason the isset() function should return anything
different when used within the foreach() declaration block.

Reproduce code:
---
class NormalClass
{
public $a, $b, $c;

public function __construct()
{
$this-a = 'a';
$this-b = 'b';
$this-c = 'c';
}
}

class ArrayClass implements Iterator
{
private $internal_array;

public function __construct()
{
$this-internal_array = array('a', 'b', 'c');
}

public function key()
{
return key($this-nodes);
}

public function current()
{
return current($this-nodes);
}

public function next()
{
next($this-nodes);
}

public function valid()
{
return (current($this-nodes) !== false) ? true : false;
}

public function rewind()
{