php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #37046 foreach breaks static scope (works in 5.1)
Submitted: 2006-04-11 21:43 UTC Modified: 2006-04-13 06:17 UTC
From: karoly at negyesi dot net Assigned: dmitry
Status: Closed Package: Scripting Engine problem
PHP Version: 4CVS-2006-04-12 OS: Linux
Private report: No CVE-ID:
 [2006-04-11 21:43 UTC] karoly at negyesi dot net
Description:
------------
foreach changes the array pointer of a static in another function.


Reproduce code:
---------------
<?php
function storage($key) {
  // uncomment the following line to see the expected result
  // return array('x', 'y'); 
  static $storage = array('a' => array('x', 'y'));
  return $storage[$key];
}
function invoke($op) {
  foreach (storage('a') as $k => $function) {
    echo "$op $k\n";
    $function($op);
  }
}
function x($op) {
  if ($op == 'op1') invoke('op2');
}
function y() {
}
invoke('op1');


Expected result:
----------------
op1 0
op2 0
op2 1
op1 1

Actual result:
--------------
op1 0
op2 0
op2 1


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2006-04-11 21:52 UTC] karoly at negyesi dot net
function storage() {
  static $storage = array('x', 'y');
  return $storage;
}

works as well.
 [2006-04-11 22:26 UTC] tony2001@php.net
You are using the same array in nested foreach() loops.
Apparently the array pointer is moved is the parent loop, which affect the nested one.
No bug here.
 [2006-04-11 23:01 UTC] karoly at negyesi dot net
I think this is still a bug. See my first comment -- that differs very slightly and yet it works.
 [2006-04-12 00:08 UTC] karoly at negyesi dot net
I thought best is if I provide one script...
<?php
function s($key) {
  static $storage = array('a' => array('x', 'y'));
  return $storage[$key];
}
function s1($key) {
  static $storage = array('a' => array('x', 'y'));
  return (array)$storage[$key];
}
function s2() {
  static $storage = array('x', 'y');
  return $storage;
}
function invoke($op, $st) {
  foreach ($st('a') as $k => $function) {
    echo "$op $k\n";
    $function($op, $st);
  }
}
function x($op, $st) {
  if ($op == 'op1') invoke('op2', $st);
}
function y() {
}
invoke('op1', 's');
echo "\n";
invoke('op1', 's1');
echo "\n";
invoke('op1', 's2');
?>
You get

op1 0
op2 0
op2 1

op1 0
op2 0
op2 1
op1 1

op1 0
op2 0
op2 1
op1 1

if this is not a bug then why they differ?
 [2006-04-12 10:35 UTC] dmitry@php.net
The simplified example:

Reproduce code:
---------------
<?php
function s() {
  static $storage = array(array('x', 'y'));
  return $storage[0];
}

foreach (s('a') as $k => $function) {
  echo "op1 $k\n";
  if ($k == 0) {
    foreach (s('a') as $k => $function) {
      echo "op2 $k\n";
    }
  }
}
?>
Expected result:
----------------
op1 0
op2 0
op2 1
op1 1

Actual result:
--------------
op1 0
op2 0
op2 1

The bug is similar to bug #35106 (nested foreach fails when array variable has a reference), but has different reason.

 [2006-04-12 11:38 UTC] dmitry@php.net
Fixed in CVS HEAD and PHP_5_1.
 [2006-04-12 14:07 UTC] karoly at negyesi dot net
Please fix in 4.x, too. Thanks.
 [2006-04-12 21:57 UTC] derick@php.net
Dmitry, please also fix this in PHP 4.4.
 [2006-04-13 06:17 UTC] dmitry@php.net
Fixed in PHP_4_4 too.
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Sat Apr 19 06:02:27 2014 UTC