php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #33031 foreach fails to continue after returning from a recursion call
Submitted: 2005-05-14 03:49 UTC Modified: 2005-05-16 00:17 UTC
From: jxmaster at msn dot com Assigned:
Status: Not a bug Package: Arrays related
PHP Version: 4.3.11 OS: windowsxp
Private report: No CVE-ID: None
View Add Comment Developer Edit
Anyone can comment on a bug. Have a simpler test case? Does it work for you on a different platform? Let us know!
Just going to say 'Me too!'? Don't clutter the database with that please !
Your email address:
MUST BE VALID
Solve the problem:
35 - 26 = ?
Subscribe to this entry?

 
 [2005-05-14 03:49 UTC] jxmaster at msn dot com
Description:
------------
'foreach' fails to continue visiting the following items in the array after returning from a recursion function call. I understand that 'foreach' works on the copy of the array, but I think it cannot explain the situation. Because after returning from the recursion call, the memory space before the call should be popped out from the running enviorenment stack. Hence, foreach should not feel that its execution has been interrupted by the recursion call.
If I change the structure of the array slightly and use for loop to replace foreach the function get the expected value. 
Following is the revised version:
function recurGetDescdendant($all, $current, $descendant) {
 $length = count($all);
 for ($i = 0; $i < $length; $i++) {
 	$userid = $all[$i][0];
 	$parent = $all[$i][1];
 	if ($parent == $current) {
    $descendant[] = $userid;
    $cdescendant = array();
    recurGetDescdendant(&$all, $userid, &$cdescendant);
    $descendant = array_merge($descendant, $cdescendant);
  }  }  }
//key represents the user id; value reprents the parent's user id of this user. for example: 6 => 1 means user 6's parent is user 1
  $all = array(array(1,0), array(2,0), array(3,0), array(4,0), array(5,0), array(6,1), array(7,1), array(11,7), array(12,11), array(13,11) );
  $descendant = array();
  recurGetDescdendant(&$all, 1, &$descendant);
  foreach ($descendant as $value) echo $value . "<br>\n";

Reproduce code:
---------------
function recurGetDescdendant($all, $current, $descendant) {
 foreach ($all as $userid => $parent) {
   if ($parent == $current) {
    $descendant[] = $userid;
    $cdescendant = array();
    recurGetDescdendant(&$all, $userid, &$cdescendant);
    $descendant = array_merge($descendant, $cdescendant);
  }  }  }
//key represents the user id; value reprents the parent's user id of this user. for example: 6 => 1 means user 6's parent is user 1
  $all = array(1 => 0, 2 => 0, 3 => 0, 4 => 0, 5 => 0, 6 => 1, 7 => 1, 11 => 7, 12 => 11, 13 => 11 );
  $descendant = array();
  recurGetDescdendant(&$all, 1, &$descendant);
  foreach ($descendant as $value) echo $value . "<br>\n";

Expected result:
----------------
6<br>
7<br>
11<br>
12<br>
13<br>

Actual result:
--------------
6<br>

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2005-05-14 19:30 UTC] tony2001@php.net
Please try to provide more readable reproduce code.
 [2005-05-15 02:24 UTC] jxmaster at msn dot com
Sorry for the reproduce code, but for the line limit, I have no choice. 

//--------------------------------------
// reproduce code
//--------------------------------------
function recurGetDescdendant($all, $current, $descendant)
{
 foreach ($all as $userid => $parent)
 {
   if ($parent == $current)
   {
    $descendant[] = $userid;
    $cdescendant = array();
    recurGetDescdendant(&$all, $userid, &$cdescendant);
    $descendant = array_merge($descendant, $cdescendant);
   }
 }
}
/*key represents the user id; value reprents the parent's user id of this user. for example: 6 => 1 means user 6's parent is user 1*/
$all = array(1 => 0, 2 => 0, 3 => 0, 4 => 0, 5 => 0, 6 => 1, 7 => 1, 11 => 7, 12 => 11, 13 => 11 );
$descendant = array();
recurGetDescdendant(&$all, 1, &$descendant);
foreach ($descendant as $value) echo $value . "<br>\n";
 [2005-05-16 00:17 UTC] sniper@php.net
RTFM: http://www.php.net/foreach

(that note about pointer being reset..and working with copy..)


 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Apr 30 16:01:29 2024 UTC