php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #41929 Foreach on object does not iterate over all visible properties
Submitted: 2007-07-08 20:03 UTC Modified: 2007-07-24 11:40 UTC
From: robin at soal dot org Assigned: dmitry
Status: Closed Package: Feature/Change Request
PHP Version: 5CVS-2007-07-08 (snap) OS: Windows
Private report: No CVE-ID:
 [2007-07-08 20:03 UTC] robin at soal dot org
Description:
------------
The documentation states that "all visible properties will be used for the iteration" when foreach'ing over an object.
Below is a case where this is not true.

Reproduce code:
---------------
<?php
class C {

  private $priv = "A private variable";

  function doLoop() {
    echo "Proof that the private is visible: " . $this->priv . "\n";
    foreach ($this as $k=>$v) {
      echo "The private is visible so should be accessed in the loop:\n";
      echo "-> $k: $v";
    }
  }
  
}

class D extends C {}

$myD = new D;
$myD->doLoop();
?>

Expected result:
----------------
Proof that the private is visible: A private variable
The private is visible so should be accessed in the loop:
-> priv: A private variable

Actual result:
--------------
Proof that the private is visible: A private variable

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2007-07-09 02:58 UTC] judas dot iscariote at gmail dot com
How do you understand  visibility ?

of course $priv is visible, but **in the context of class C** as you defined it as "private" !!! (hint, hint)

$this in your code is(as expected) an instance of class D not of class C ;-)

if you make $priv "protected" it will work as expected (hint,hint)
 [2007-07-09 08:31 UTC] robin at soal dot org
Hi Judas,

Thanks for the comment. I think we may have the same understanding of visibility in this case: D extends C, so $priv (which is defined in C) should only be visible on instances of D if the current context is C.

If $priv is visible when using the object operator on $this, I think it is justified that it would be visible when using foreach on $this from the same context.

In case my use of $this was confusing the issue, here's the same problem presented without $this (same expected and actual output as above):

<?php
class C {

  private $priv = "A private variable";

  static function doLoop(D $myD) {
    echo "Proof that the private is visible: " . $myD->priv . "\n";
    foreach ($myD as $k=>$v) {
      echo "The private is visible so should be accessed in the loop:\n";
      echo "-> $k: $v";
    }
  }
  
}

class D extends C {}

$myD = new D;
C::doLoop($myD);
?>
 [2007-07-09 10:00 UTC] robin at soal dot org
If this is accepted as a bug and fixed, then test http://lxr.php.net/source/php-src/tests/classes/visibility_005.phpt will need to be updated.

The private $c should be visible from f() even when invoked on an instance of derived, so the expected output should be as follows (note the extra c=>3 under ===derived::function===):

--EXPECT--
===base::function===
a=>1
b=>2
c=>3
d=>4
===base,foreach===
a=>1
d=>4
===derived::function===
a=>1
b=>2
c=>3
d=>4
===derived,foreach===
a=>1
d=>4
 [2007-07-24 11:40 UTC] dmitry@php.net
This bug has been fixed in CVS.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
 
Thank you for the report, and for helping us make PHP better.


 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Sat Apr 19 17:01:54 2014 UTC