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
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: jxmaster at msn dot com
New email:
PHP Version: OS:

 

 [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: Thu Apr 18 12:01:28 2024 UTC