]> granicus.if.org Git - php/commitdiff
New tests for foreach loops. These were written by another member of the Projectzero...
authorRobert Nicholson <nicholsr@php.net>
Sun, 7 Jun 2009 21:03:48 +0000 (21:03 +0000)
committerRobert Nicholson <nicholsr@php.net>
Sun, 7 Jun 2009 21:03:48 +0000 (21:03 +0000)
17 files changed:
tests/lang/foreachLoop.001.phpt [new file with mode: 0644]
tests/lang/foreachLoop.002.phpt [new file with mode: 0644]
tests/lang/foreachLoop.003.phpt [new file with mode: 0644]
tests/lang/foreachLoop.004.phpt [new file with mode: 0644]
tests/lang/foreachLoop.005.phpt [new file with mode: 0644]
tests/lang/foreachLoop.006.phpt [new file with mode: 0644]
tests/lang/foreachLoop.007.phpt [new file with mode: 0644]
tests/lang/foreachLoop.008.phpt [new file with mode: 0644]
tests/lang/foreachLoop.009.phpt [new file with mode: 0644]
tests/lang/foreachLoop.010.phpt [new file with mode: 0644]
tests/lang/foreachLoop.011.phpt [new file with mode: 0644]
tests/lang/foreachLoop.012.phpt [new file with mode: 0644]
tests/lang/foreachLoop.013.phpt [new file with mode: 0644]
tests/lang/foreachLoop.014.phpt [new file with mode: 0644]
tests/lang/foreachLoop.015.phpt [new file with mode: 0644]
tests/lang/foreachLoop.016.phpt [new file with mode: 0644]
tests/lang/foreachLoop.017.phpt [new file with mode: 0644]

diff --git a/tests/lang/foreachLoop.001.phpt b/tests/lang/foreachLoop.001.phpt
new file mode 100644 (file)
index 0000000..164cac6
--- /dev/null
@@ -0,0 +1,64 @@
+--TEST--\r
+Foreach loop tests - basic loop with just value and key => value.\r
+--FILE--\r
+<?php\r
+\r
+$a = array("a","b","c");\r
+\r
+foreach ($a as $v) {\r
+       var_dump($v);\r
+}\r
+foreach ($a as $k => $v) {\r
+       var_dump($k, $v);\r
+}\r
+//check key and value after the loop.\r
+var_dump($k, $v);\r
+\r
+echo "\n";\r
+//Dynamic array\r
+foreach (array("d","e","f") as $v) {\r
+       var_dump($v);\r
+}\r
+foreach (array("d","e","f") as $k => $v) {\r
+       var_dump($k, $v);\r
+}\r
+//check key and value after the loop.\r
+var_dump($k, $v);\r
+\r
+echo "\n";\r
+//Ensure counter is advanced during loop\r
+$a=array("a","b","c");\r
+foreach ($a as $v);\r
+var_dump(current($a));\r
+$a=array("a","b","c");\r
+foreach ($a as &$v);\r
+var_dump(current($a));\r
+\r
+?>\r
+--EXPECT--\r
+string(1) "a"\r
+string(1) "b"\r
+string(1) "c"\r
+int(0)\r
+string(1) "a"\r
+int(1)\r
+string(1) "b"\r
+int(2)\r
+string(1) "c"\r
+int(2)\r
+string(1) "c"\r
+\r
+string(1) "d"\r
+string(1) "e"\r
+string(1) "f"\r
+int(0)\r
+string(1) "d"\r
+int(1)\r
+string(1) "e"\r
+int(2)\r
+string(1) "f"\r
+int(2)\r
+string(1) "f"\r
+\r
+bool(false)\r
+bool(false)
\ No newline at end of file
diff --git a/tests/lang/foreachLoop.002.phpt b/tests/lang/foreachLoop.002.phpt
new file mode 100644 (file)
index 0000000..e3000c7
--- /dev/null
@@ -0,0 +1,173 @@
+--TEST--\r
+Foreach loop tests - modifying the array during the loop.\r
+--FILE--\r
+<?php\r
+\r
+echo "\nDirectly changing array values.\n";\r
+$a = array("original.1","original.2","original.3");\r
+foreach ($a as $k=>$v) {\r
+       $a[$k]="changed.$k";\r
+       var_dump($v);\r
+}\r
+var_dump($a);\r
+\r
+echo "\nModifying the foreach \$value.\n";\r
+$a = array("original.1","original.2","original.3");\r
+foreach ($a as $k=>$v) {\r
+       $v="changed.$k";\r
+}\r
+var_dump($a);\r
+\r
+\r
+echo "\nModifying the foreach &\$value.\n";\r
+$a = array("original.1","original.2","original.3");\r
+foreach ($a as $k=>&$v) {\r
+       $v="changed.$k";\r
+}\r
+var_dump($a);\r
+\r
+echo "\nPushing elements onto an unreferenced array.\n";\r
+$a = array("original.1","original.2","original.3");\r
+$counter=0;\r
+foreach ($a as $v) {\r
+       array_push($a, "new.$counter");\r
+\r
+       //avoid infinite loop if test is failing\r
+    if ($counter++>10) {\r
+       echo "Loop detected\n";\r
+       break;          \r
+    }\r
+}\r
+var_dump($a);\r
+\r
+echo "\nPushing elements onto an unreferenced array, using &\$value.\n";\r
+$a = array("original.1","original.2","original.3");\r
+$counter=0;\r
+foreach ($a as &$v) {\r
+       array_push($a, "new.$counter");\r
+\r
+       //avoid infinite loop if test is failing\r
+    if ($counter++>10) {\r
+       echo "Loop detected\n";\r
+       break;          \r
+    }  \r
+}\r
+var_dump($a);\r
+\r
+echo "\nPopping elements off an unreferenced array.\n";\r
+$a = array("original.1","original.2","original.3");\r
+foreach ($a as $v) {\r
+       array_pop($a);\r
+       var_dump($v);   \r
+}\r
+var_dump($a);\r
+\r
+echo "\nPopping elements off an unreferenced array, using &\$value.\n";\r
+$a = array("original.1","original.2","original.3");\r
+foreach ($a as &$v) {\r
+       array_pop($a);\r
+       var_dump($v);\r
+}\r
+var_dump($a);\r
+\r
+?>\r
+--EXPECT--\r
+\r
+Directly changing array values.\r
+string(10) "original.1"\r
+string(10) "original.2"\r
+string(10) "original.3"\r
+array(3) {\r
+  [0]=>\r
+  string(9) "changed.0"\r
+  [1]=>\r
+  string(9) "changed.1"\r
+  [2]=>\r
+  string(9) "changed.2"\r
+}\r
+\r
+Modifying the foreach $value.\r
+array(3) {\r
+  [0]=>\r
+  string(10) "original.1"\r
+  [1]=>\r
+  string(10) "original.2"\r
+  [2]=>\r
+  string(10) "original.3"\r
+}\r
+\r
+Modifying the foreach &$value.\r
+array(3) {\r
+  [0]=>\r
+  string(9) "changed.0"\r
+  [1]=>\r
+  string(9) "changed.1"\r
+  [2]=>\r
+  &string(9) "changed.2"\r
+}\r
+\r
+Pushing elements onto an unreferenced array.\r
+array(6) {\r
+  [0]=>\r
+  string(10) "original.1"\r
+  [1]=>\r
+  string(10) "original.2"\r
+  [2]=>\r
+  string(10) "original.3"\r
+  [3]=>\r
+  string(5) "new.0"\r
+  [4]=>\r
+  string(5) "new.1"\r
+  [5]=>\r
+  string(5) "new.2"\r
+}\r
+\r
+Pushing elements onto an unreferenced array, using &$value.\r
+Loop detected\r
+array(15) {\r
+  [0]=>\r
+  string(10) "original.1"\r
+  [1]=>\r
+  string(10) "original.2"\r
+  [2]=>\r
+  string(10) "original.3"\r
+  [3]=>\r
+  string(5) "new.0"\r
+  [4]=>\r
+  string(5) "new.1"\r
+  [5]=>\r
+  string(5) "new.2"\r
+  [6]=>\r
+  string(5) "new.3"\r
+  [7]=>\r
+  string(5) "new.4"\r
+  [8]=>\r
+  string(5) "new.5"\r
+  [9]=>\r
+  string(5) "new.6"\r
+  [10]=>\r
+  string(5) "new.7"\r
+  [11]=>\r
+  &string(5) "new.8"\r
+  [12]=>\r
+  string(5) "new.9"\r
+  [13]=>\r
+  string(6) "new.10"\r
+  [14]=>\r
+  string(6) "new.11"\r
+}\r
+\r
+Popping elements off an unreferenced array.\r
+string(10) "original.1"\r
+string(10) "original.2"\r
+string(10) "original.3"\r
+array(0) {\r
+}\r
+\r
+Popping elements off an unreferenced array, using &$value.\r
+string(10) "original.1"\r
+string(10) "original.2"\r
+array(1) {\r
+  [0]=>\r
+  string(10) "original.1"\r
+}
\ No newline at end of file
diff --git a/tests/lang/foreachLoop.003.phpt b/tests/lang/foreachLoop.003.phpt
new file mode 100644 (file)
index 0000000..d554d0d
--- /dev/null
@@ -0,0 +1,46 @@
+--TEST--\r
+Foreach loop tests - error case: not an array.\r
+--FILE--\r
+<?php\r
+echo "\nNot an array.\n";\r
+$a = TRUE;\r
+foreach ($a as $v) {\r
+       var_dump($v);\r
+}\r
+\r
+$a = null;\r
+foreach ($a as $v) {\r
+       var_dump($v);\r
+}\r
+\r
+$a = 1;\r
+foreach ($a as $v) {\r
+       var_dump($v);\r
+}\r
+\r
+$a = 1.5;\r
+foreach ($a as $v) {\r
+       var_dump($v);\r
+}\r
+\r
+$a = "hello";\r
+foreach ($a as $v) {\r
+       var_dump($v);\r
+}\r
+\r
+echo "done.\n";\r
+?>\r
+--EXPECTF--\r
+\r
+Not an array.\r
+\r
+Warning: Invalid argument supplied for foreach() in %s on line 4\r
+\r
+Warning: Invalid argument supplied for foreach() in %s on line 9\r
+\r
+Warning: Invalid argument supplied for foreach() in %s on line 14\r
+\r
+Warning: Invalid argument supplied for foreach() in %s on line 19\r
+\r
+Warning: Invalid argument supplied for foreach() in %s on line 24\r
+done.\r
diff --git a/tests/lang/foreachLoop.004.phpt b/tests/lang/foreachLoop.004.phpt
new file mode 100644 (file)
index 0000000..8cc6094
--- /dev/null
@@ -0,0 +1,76 @@
+--TEST--\r
+Foreach loop tests - using an array element as the $value\r
+--FILE--\r
+<?php\r
+\r
+$a=array("a", "b", "c");\r
+$v=array();\r
+foreach($a as $v[0]) {\r
+       var_dump($v);\r
+}\r
+var_dump($a);\r
+var_dump($v);\r
+\r
+echo "\n";\r
+$a=array("a", "b", "c");\r
+$v=array();\r
+foreach($a as $k=>$v[0]) {\r
+       var_dump($k, $v);\r
+}\r
+var_dump($a);\r
+var_dump($k, $v);\r
+?>\r
+--EXPECT--\r
+array(1) {\r
+  [0]=>\r
+  string(1) "a"\r
+}\r
+array(1) {\r
+  [0]=>\r
+  string(1) "b"\r
+}\r
+array(1) {\r
+  [0]=>\r
+  string(1) "c"\r
+}\r
+array(3) {\r
+  [0]=>\r
+  string(1) "a"\r
+  [1]=>\r
+  string(1) "b"\r
+  [2]=>\r
+  string(1) "c"\r
+}\r
+array(1) {\r
+  [0]=>\r
+  string(1) "c"\r
+}\r
+\r
+int(0)\r
+array(1) {\r
+  [0]=>\r
+  string(1) "a"\r
+}\r
+int(1)\r
+array(1) {\r
+  [0]=>\r
+  string(1) "b"\r
+}\r
+int(2)\r
+array(1) {\r
+  [0]=>\r
+  string(1) "c"\r
+}\r
+array(3) {\r
+  [0]=>\r
+  string(1) "a"\r
+  [1]=>\r
+  string(1) "b"\r
+  [2]=>\r
+  string(1) "c"\r
+}\r
+int(2)\r
+array(1) {\r
+  [0]=>\r
+  string(1) "c"\r
+}
\ No newline at end of file
diff --git a/tests/lang/foreachLoop.005.phpt b/tests/lang/foreachLoop.005.phpt
new file mode 100644 (file)
index 0000000..ae6ed3a
--- /dev/null
@@ -0,0 +1,23 @@
+--TEST--\r
+Foreach loop tests - modifying the array during the loop: special case. Behaviour is good since php 5.2.2.\r
+--FILE--\r
+<?php\r
+$a = array("original.0","original.1","original.2");\r
+foreach ($a as $k=>&$v){\r
+  $a[$k] = "changed.$k";\r
+  echo "After changing \$a directly, \$v@$k is: $v\n";\r
+}\r
+//--- Expected output:\r
+//After changing $a directly, $v@0 is: changed.0\r
+//After changing $a directly, $v@1 is: changed.1\r
+//After changing $a directly, $v@2 is: changed.2\r
+//--- Actual output from php.net before 5.2.2:\r
+//After changing $a directly, $v@0 is: changed.0\r
+//After changing $a directly, $v@1 is: original.1\r
+//After changing $a directly, $v@2 is: original.2\r
+\r
+?>\r
+--EXPECT--\r
+After changing $a directly, $v@0 is: changed.0\r
+After changing $a directly, $v@1 is: changed.1\r
+After changing $a directly, $v@2 is: changed.2\r
diff --git a/tests/lang/foreachLoop.006.phpt b/tests/lang/foreachLoop.006.phpt
new file mode 100644 (file)
index 0000000..a90f924
--- /dev/null
@@ -0,0 +1,11 @@
+--TEST--\r
+Foreach loop tests - error case: key is a reference.\r
+--FILE--\r
+<?php\r
+$a = array("a","b","c");\r
+foreach ($a as &$k=>$v) {\r
+  var_dump($v);\r
+}\r
+?>\r
+--EXPECTF--\r
+Fatal error: Key element cannot be a reference in %s on line 3
\ No newline at end of file
diff --git a/tests/lang/foreachLoop.007.phpt b/tests/lang/foreachLoop.007.phpt
new file mode 100644 (file)
index 0000000..f47fdc7
--- /dev/null
@@ -0,0 +1,11 @@
+--TEST--\r
+Foreach loop tests - error case: reference to constant array.\r
+--FILE--\r
+<?php\r
+echo "\nReference to constant array\n";\r
+foreach (array(1,2) as &$v) {\r
+  var_dump($v);\r
+}\r
+?>\r
+--EXPECTF--\r
+Parse error: %s on line 3\r
diff --git a/tests/lang/foreachLoop.008.phpt b/tests/lang/foreachLoop.008.phpt
new file mode 100644 (file)
index 0000000..787f43b
--- /dev/null
@@ -0,0 +1,10 @@
+--TEST--\r
+Foreach loop tests - error case: reference to constant array, with key.\r
+--FILE--\r
+<?php\r
+foreach (array(1,2) as $k=>&$v) {\r
+  var_dump($v);\r
+}\r
+?>\r
+--EXPECTF--\r
+Fatal error: Cannot create references to elements of a temporary array expression in %s on line 2\r
diff --git a/tests/lang/foreachLoop.009.phpt b/tests/lang/foreachLoop.009.phpt
new file mode 100644 (file)
index 0000000..4586a35
--- /dev/null
@@ -0,0 +1,82 @@
+--TEST--\r
+Foreach loop tests - foreach operates on the original array if the array is referenced outside the loop.\r
+--FILE--\r
+<?php\r
+// From php.net/foreach:\r
+// "Unless the array is referenced, foreach operates on a copy of the specified array."\r
+\r
+echo "\nRemove elements from a referenced array during loop\n";\r
+$refedArray=array("original.0", "original.1", "original.2");\r
+$ref=&$refedArray;\r
+foreach ($refedArray as $k=>$v1) {\r
+       array_pop($refedArray);\r
+       echo "key: $k; value: $v1\n";\r
+}\r
+\r
+echo "\nRemove elements from a referenced array during loop, using &\$value\n";\r
+$refedArray=array("original.0", "original.1", "original.2");\r
+$ref=&$refedArray;\r
+foreach ($refedArray as $k=>&$v2) {\r
+       array_pop($refedArray);\r
+       echo "key: $k; value: $v2\n";\r
+}\r
+\r
+echo "\nAdd elements to a referenced array during loop\n";\r
+$refedArray=array("original.0", "original.1", "original.2");\r
+$ref=&$refedArray;\r
+$count=0;\r
+foreach ($refedArray as $k=>$v3) {\r
+       array_push($refedArray, "new.$k");\r
+       echo "key: $k; value: $v3\n";\r
+       \r
+       if ($count++>5) {\r
+               echo "Loop detected, as expected.\n";\r
+               break;\r
+       }\r
+}\r
+\r
+echo "\nAdd elements to a referenced array during loop, using &\$value\n";\r
+$refedArray=array("original.0", "original.1", "original.2");\r
+$ref=&$refedArray;\r
+$count=0;\r
+foreach ($refedArray as $k=>&$v4) {\r
+       array_push($refedArray, "new.$k");\r
+       echo "key: $k; value: $v4\n";\r
+       \r
+       if ($count++>5) {\r
+               echo "Loop detected, as expected.\n";\r
+               break;\r
+       }\r
+}\r
+\r
+?>\r
+--EXPECT--\r
+\r
+Remove elements from a referenced array during loop\r
+key: 0; value: original.0\r
+key: 1; value: original.1\r
+\r
+Remove elements from a referenced array during loop, using &$value\r
+key: 0; value: original.0\r
+key: 1; value: original.1\r
+\r
+Add elements to a referenced array during loop\r
+key: 0; value: original.0\r
+key: 1; value: original.1\r
+key: 2; value: original.2\r
+key: 3; value: new.0\r
+key: 4; value: new.1\r
+key: 5; value: new.2\r
+key: 6; value: new.3\r
+Loop detected, as expected.\r
+\r
+Add elements to a referenced array during loop, using &$value\r
+key: 0; value: original.0\r
+key: 1; value: original.1\r
+key: 2; value: original.2\r
+key: 3; value: new.0\r
+key: 4; value: new.1\r
+key: 5; value: new.2\r
+key: 6; value: new.3\r
+Loop detected, as expected.\r
+\r
diff --git a/tests/lang/foreachLoop.010.phpt b/tests/lang/foreachLoop.010.phpt
new file mode 100644 (file)
index 0000000..a7a3e97
--- /dev/null
@@ -0,0 +1,40 @@
+--TEST--\r
+This test illustrates the impact of invoking destructors when refcount is decremented to 0 on foreach.\r
+It will pass only if the 'contentious code' in PHPValue.decReferences() is enabled.\r
+--FILE--\r
+<?php\r
+\r
+$a = array(1,2,3);\r
+$container = array(&$a);\r
+\r
+// From php.net:  \r
+//   "Unless the array is referenced, foreach operates on a copy of\r
+//    the specified array and not the array itself."\r
+// At this point, the array $a is referenced.\r
+\r
+// The following line ensures $a is no longer references as a consequence\r
+// of running the 'destructor' on $container.  \r
+$container = null;\r
+\r
+// At this point the array $a is no longer referenced, so foreach should operate on a copy of the array.\r
+// However, P8 does not invoke 'destructors' when refcount is decremented to 0.\r
+// Consequently, $a thinks it is still referenced, and foreach will operate on the array itself.\r
+// This provokes a difference in behaviour when changing the number of elements in the array while\r
+// iterating over it.  \r
+\r
+$i=0;\r
+foreach ($a as $v) {\r
+       array_push($a, 'new');\r
+       var_dump($v);\r
+       \r
+       if (++$i>10) {\r
+               echo "Infinite loop detected\n";\r
+               break;\r
+       }\r
+}\r
+\r
+?>\r
+--EXPECTF--\r
+int(1)\r
+int(2)\r
+int(3)
\ No newline at end of file
diff --git a/tests/lang/foreachLoop.011.phpt b/tests/lang/foreachLoop.011.phpt
new file mode 100644 (file)
index 0000000..94cb605
--- /dev/null
@@ -0,0 +1,34 @@
+--TEST-- \r
+Changing from an interable type to a non iterable type during the iteration \r
+--FILE--\r
+<?php\r
+echo "\nChange from array to non iterable:\n";\r
+$a = array(1,2,3);\r
+$b=&$a;\r
+foreach ($a as $v) {\r
+       var_dump($v);\r
+       $b=1;\r
+}\r
+\r
+echo "\nChange from object to non iterable:\n";\r
+$a = new stdClass;\r
+$a->a=1;\r
+$a->b=2;\r
+$b=&$a;\r
+foreach ($a as $v) {\r
+       var_dump($v);\r
+       $b='x'; \r
+}\r
+\r
+?>\r
+--EXPECTF--\r
+\r
+Change from array to non iterable:\r
+int(1)\r
+\r
+Warning: Invalid argument supplied for foreach() in %s on line 5\r
+\r
+Change from object to non iterable:\r
+int(1)\r
+\r
+Warning: Invalid argument supplied for foreach() in %s on line 15
\ No newline at end of file
diff --git a/tests/lang/foreachLoop.012.phpt b/tests/lang/foreachLoop.012.phpt
new file mode 100644 (file)
index 0000000..1165b74
--- /dev/null
@@ -0,0 +1,494 @@
+--TEST--\r
+Directly modifying an unreferenced array when foreach'ing over it.\r
+--FILE--\r
+<?php\r
+\r
+define('MAX_LOOPS',5);\r
+\r
+function withRefValue($elements, $transform) {\r
+       echo "\n---( Array with $elements element(s): )---\n";\r
+       //Build array:\r
+       for ($i=0; $i<$elements; $i++) {\r
+               $a[] = "v.$i";\r
+       }\r
+       $counter=0;\r
+       \r
+       echo "--> State of array before loop:\n";\r
+       var_dump($a);\r
+       \r
+       echo "--> Do loop:\n";  \r
+       foreach ($a as $k=>$v) {\r
+               echo "     iteration $counter:  \$k=$k; \$v=$v\n";\r
+               eval($transform);\r
+               $counter++;\r
+               if ($counter>MAX_LOOPS) {\r
+                       echo "  ** Stuck in a loop! **\n";\r
+                       break;\r
+               }\r
+       }\r
+       \r
+       echo "--> State of array after loop:\n";\r
+       var_dump($a);\r
+}\r
+\r
+\r
+echo "\nPopping elements off end of an unreferenced array";\r
+$transform = 'array_pop($a);';\r
+withRefValue(1, $transform);\r
+withRefValue(2, $transform);\r
+withRefValue(3, $transform);\r
+withRefValue(4, $transform);\r
+\r
+echo "\n\n\nShift elements off start of an unreferenced array";\r
+$transform = 'array_shift($a);';\r
+withRefValue(1, $transform);\r
+withRefValue(2, $transform);\r
+withRefValue(3, $transform);\r
+withRefValue(4, $transform);\r
+\r
+echo "\n\n\nRemove current element of an unreferenced array";\r
+$transform = 'unset($a[$k]);';\r
+withRefValue(1, $transform);\r
+withRefValue(2, $transform);\r
+withRefValue(3, $transform);\r
+withRefValue(4, $transform);\r
+\r
+echo "\n\n\nAdding elements to the end of an unreferenced array";\r
+$transform = 'array_push($a, "new.$counter");';\r
+withRefValue(1, $transform);\r
+withRefValue(2, $transform);\r
+withRefValue(3, $transform);\r
+withRefValue(4, $transform);\r
+\r
+echo "\n\n\nAdding elements to the start of an unreferenced array";\r
+$transform = 'array_unshift($a, "new.$counter");';\r
+withRefValue(1, $transform);\r
+withRefValue(2, $transform);\r
+withRefValue(3, $transform);\r
+withRefValue(4, $transform);\r
+\r
+?>\r
+--EXPECTF--\r
+\r
+Popping elements off end of an unreferenced array\r
+---( Array with 1 element(s): )---\r
+--> State of array before loop:\r
+array(1) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+--> State of array after loop:\r
+array(0) {\r
+}\r
+\r
+---( Array with 2 element(s): )---\r
+--> State of array before loop:\r
+array(2) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=1; $v=v.1\r
+--> State of array after loop:\r
+array(0) {\r
+}\r
+\r
+---( Array with 3 element(s): )---\r
+--> State of array before loop:\r
+array(3) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(3) "v.2"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=1; $v=v.1\r
+     iteration 2:  $k=2; $v=v.2\r
+--> State of array after loop:\r
+array(0) {\r
+}\r
+\r
+---( Array with 4 element(s): )---\r
+--> State of array before loop:\r
+array(4) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(3) "v.2"\r
+  [3]=>\r
+  string(3) "v.3"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=1; $v=v.1\r
+     iteration 2:  $k=2; $v=v.2\r
+     iteration 3:  $k=3; $v=v.3\r
+--> State of array after loop:\r
+array(0) {\r
+}\r
+\r
+\r
+\r
+Shift elements off start of an unreferenced array\r
+---( Array with 1 element(s): )---\r
+--> State of array before loop:\r
+array(1) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+--> State of array after loop:\r
+array(0) {\r
+}\r
+\r
+---( Array with 2 element(s): )---\r
+--> State of array before loop:\r
+array(2) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=1; $v=v.1\r
+--> State of array after loop:\r
+array(0) {\r
+}\r
+\r
+---( Array with 3 element(s): )---\r
+--> State of array before loop:\r
+array(3) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(3) "v.2"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=1; $v=v.1\r
+     iteration 2:  $k=2; $v=v.2\r
+--> State of array after loop:\r
+array(0) {\r
+}\r
+\r
+---( Array with 4 element(s): )---\r
+--> State of array before loop:\r
+array(4) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(3) "v.2"\r
+  [3]=>\r
+  string(3) "v.3"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=1; $v=v.1\r
+     iteration 2:  $k=2; $v=v.2\r
+     iteration 3:  $k=3; $v=v.3\r
+--> State of array after loop:\r
+array(0) {\r
+}\r
+\r
+\r
+\r
+Remove current element of an unreferenced array\r
+---( Array with 1 element(s): )---\r
+--> State of array before loop:\r
+array(1) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+--> State of array after loop:\r
+array(0) {\r
+}\r
+\r
+---( Array with 2 element(s): )---\r
+--> State of array before loop:\r
+array(2) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=1; $v=v.1\r
+--> State of array after loop:\r
+array(0) {\r
+}\r
+\r
+---( Array with 3 element(s): )---\r
+--> State of array before loop:\r
+array(3) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(3) "v.2"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=1; $v=v.1\r
+     iteration 2:  $k=2; $v=v.2\r
+--> State of array after loop:\r
+array(0) {\r
+}\r
+\r
+---( Array with 4 element(s): )---\r
+--> State of array before loop:\r
+array(4) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(3) "v.2"\r
+  [3]=>\r
+  string(3) "v.3"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=1; $v=v.1\r
+     iteration 2:  $k=2; $v=v.2\r
+     iteration 3:  $k=3; $v=v.3\r
+--> State of array after loop:\r
+array(0) {\r
+}\r
+\r
+\r
+\r
+Adding elements to the end of an unreferenced array\r
+---( Array with 1 element(s): )---\r
+--> State of array before loop:\r
+array(1) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+--> State of array after loop:\r
+array(2) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(5) "new.0"\r
+}\r
+\r
+---( Array with 2 element(s): )---\r
+--> State of array before loop:\r
+array(2) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=1; $v=v.1\r
+--> State of array after loop:\r
+array(4) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(5) "new.0"\r
+  [3]=>\r
+  string(5) "new.1"\r
+}\r
+\r
+---( Array with 3 element(s): )---\r
+--> State of array before loop:\r
+array(3) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(3) "v.2"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=1; $v=v.1\r
+     iteration 2:  $k=2; $v=v.2\r
+--> State of array after loop:\r
+array(6) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(3) "v.2"\r
+  [3]=>\r
+  string(5) "new.0"\r
+  [4]=>\r
+  string(5) "new.1"\r
+  [5]=>\r
+  string(5) "new.2"\r
+}\r
+\r
+---( Array with 4 element(s): )---\r
+--> State of array before loop:\r
+array(4) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(3) "v.2"\r
+  [3]=>\r
+  string(3) "v.3"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=1; $v=v.1\r
+     iteration 2:  $k=2; $v=v.2\r
+     iteration 3:  $k=3; $v=v.3\r
+--> State of array after loop:\r
+array(8) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(3) "v.2"\r
+  [3]=>\r
+  string(3) "v.3"\r
+  [4]=>\r
+  string(5) "new.0"\r
+  [5]=>\r
+  string(5) "new.1"\r
+  [6]=>\r
+  string(5) "new.2"\r
+  [7]=>\r
+  string(5) "new.3"\r
+}\r
+\r
+\r
+\r
+Adding elements to the start of an unreferenced array\r
+---( Array with 1 element(s): )---\r
+--> State of array before loop:\r
+array(1) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+--> State of array after loop:\r
+array(2) {\r
+  [0]=>\r
+  string(5) "new.0"\r
+  [1]=>\r
+  string(3) "v.0"\r
+}\r
+\r
+---( Array with 2 element(s): )---\r
+--> State of array before loop:\r
+array(2) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=1; $v=v.1\r
+--> State of array after loop:\r
+array(4) {\r
+  [0]=>\r
+  string(5) "new.1"\r
+  [1]=>\r
+  string(5) "new.0"\r
+  [2]=>\r
+  string(3) "v.0"\r
+  [3]=>\r
+  string(3) "v.1"\r
+}\r
+\r
+---( Array with 3 element(s): )---\r
+--> State of array before loop:\r
+array(3) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(3) "v.2"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=1; $v=v.1\r
+     iteration 2:  $k=2; $v=v.2\r
+--> State of array after loop:\r
+array(6) {\r
+  [0]=>\r
+  string(5) "new.2"\r
+  [1]=>\r
+  string(5) "new.1"\r
+  [2]=>\r
+  string(5) "new.0"\r
+  [3]=>\r
+  string(3) "v.0"\r
+  [4]=>\r
+  string(3) "v.1"\r
+  [5]=>\r
+  string(3) "v.2"\r
+}\r
+\r
+---( Array with 4 element(s): )---\r
+--> State of array before loop:\r
+array(4) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(3) "v.2"\r
+  [3]=>\r
+  string(3) "v.3"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=1; $v=v.1\r
+     iteration 2:  $k=2; $v=v.2\r
+     iteration 3:  $k=3; $v=v.3\r
+--> State of array after loop:\r
+array(8) {\r
+  [0]=>\r
+  string(5) "new.3"\r
+  [1]=>\r
+  string(5) "new.2"\r
+  [2]=>\r
+  string(5) "new.1"\r
+  [3]=>\r
+  string(5) "new.0"\r
+  [4]=>\r
+  string(3) "v.0"\r
+  [5]=>\r
+  string(3) "v.1"\r
+  [6]=>\r
+  string(3) "v.2"\r
+  [7]=>\r
+  string(3) "v.3"\r
+}\r
diff --git a/tests/lang/foreachLoop.013.phpt b/tests/lang/foreachLoop.013.phpt
new file mode 100644 (file)
index 0000000..3dec119
--- /dev/null
@@ -0,0 +1,555 @@
+--TEST--\r
+Directly modifying an unreferenced array when foreach'ing over it while using &$value syntax.\r
+--FILE--\r
+<?php\r
+\r
+define('MAX_LOOPS',5);\r
+\r
+function withRefValue($elements, $transform) {\r
+       echo "\n---( Array with $elements element(s): )---\n";\r
+       //Build array:\r
+       for ($i=0; $i<$elements; $i++) {\r
+               $a[] = "v.$i";\r
+       }\r
+       $counter=0;\r
+       \r
+       echo "--> State of array before loop:\n";\r
+       var_dump($a);\r
+       \r
+       echo "--> Do loop:\n";  \r
+       foreach ($a as $k=>&$v) {\r
+               echo "     iteration $counter:  \$k=$k; \$v=$v\n";\r
+               eval($transform);\r
+               $counter++;\r
+               if ($counter>MAX_LOOPS) {\r
+                       echo "  ** Stuck in a loop! **\n";\r
+                       break;\r
+               }\r
+       }\r
+       \r
+       echo "--> State of array after loop:\n";\r
+       var_dump($a);\r
+}\r
+\r
+\r
+echo "\nPopping elements off end of an unreferenced array, using &\$value.";\r
+$transform = 'array_pop($a);';\r
+withRefValue(1, $transform);\r
+withRefValue(2, $transform);\r
+withRefValue(3, $transform);\r
+withRefValue(4, $transform);\r
+\r
+echo "\n\n\nShift elements off start of an unreferenced array, using &\$value.";\r
+$transform = 'array_shift($a);';\r
+withRefValue(1, $transform);\r
+withRefValue(2, $transform);\r
+withRefValue(3, $transform);\r
+withRefValue(4, $transform);\r
+\r
+echo "\n\n\nRemove current element of an unreferenced array, using &\$value.";\r
+$transform = 'unset($a[$k]);';\r
+withRefValue(1, $transform);\r
+withRefValue(2, $transform);\r
+withRefValue(3, $transform);\r
+withRefValue(4, $transform);\r
+\r
+echo "\n\n\nAdding elements to the end of an unreferenced array, using &\$value.";\r
+$transform = 'array_push($a, "new.$counter");';\r
+withRefValue(1, $transform);\r
+withRefValue(2, $transform);\r
+withRefValue(3, $transform);\r
+withRefValue(4, $transform);\r
+\r
+echo "\n\n\nAdding elements to the start of an unreferenced array, using &\$value.";\r
+$transform = 'array_unshift($a, "new.$counter");';\r
+withRefValue(1, $transform);\r
+withRefValue(2, $transform);\r
+withRefValue(3, $transform);\r
+withRefValue(4, $transform);\r
+\r
+?>\r
+--EXPECTF--\r
+\r
+Popping elements off end of an unreferenced array, using &$value.\r
+---( Array with 1 element(s): )---\r
+--> State of array before loop:\r
+array(1) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+--> State of array after loop:\r
+array(0) {\r
+}\r
+\r
+---( Array with 2 element(s): )---\r
+--> State of array before loop:\r
+array(2) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=0; $v=v.0\r
+--> State of array after loop:\r
+array(0) {\r
+}\r
+\r
+---( Array with 3 element(s): )---\r
+--> State of array before loop:\r
+array(3) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(3) "v.2"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=1; $v=v.1\r
+--> State of array after loop:\r
+array(1) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+}\r
+\r
+---( Array with 4 element(s): )---\r
+--> State of array before loop:\r
+array(4) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(3) "v.2"\r
+  [3]=>\r
+  string(3) "v.3"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=1; $v=v.1\r
+     iteration 2:  $k=0; $v=v.0\r
+     iteration 3:  $k=0; $v=v.0\r
+--> State of array after loop:\r
+array(0) {\r
+}\r
+\r
+\r
+\r
+Shift elements off start of an unreferenced array, using &$value.\r
+---( Array with 1 element(s): )---\r
+--> State of array before loop:\r
+array(1) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+--> State of array after loop:\r
+array(0) {\r
+}\r
+\r
+---( Array with 2 element(s): )---\r
+--> State of array before loop:\r
+array(2) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=0; $v=v.1\r
+--> State of array after loop:\r
+array(0) {\r
+}\r
+\r
+---( Array with 3 element(s): )---\r
+--> State of array before loop:\r
+array(3) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(3) "v.2"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=0; $v=v.1\r
+     iteration 2:  $k=0; $v=v.2\r
+--> State of array after loop:\r
+array(0) {\r
+}\r
+\r
+---( Array with 4 element(s): )---\r
+--> State of array before loop:\r
+array(4) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(3) "v.2"\r
+  [3]=>\r
+  string(3) "v.3"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=0; $v=v.1\r
+     iteration 2:  $k=0; $v=v.2\r
+     iteration 3:  $k=0; $v=v.3\r
+--> State of array after loop:\r
+array(0) {\r
+}\r
+\r
+\r
+\r
+Remove current element of an unreferenced array, using &$value.\r
+---( Array with 1 element(s): )---\r
+--> State of array before loop:\r
+array(1) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+--> State of array after loop:\r
+array(0) {\r
+}\r
+\r
+---( Array with 2 element(s): )---\r
+--> State of array before loop:\r
+array(2) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=1; $v=v.1\r
+--> State of array after loop:\r
+array(0) {\r
+}\r
+\r
+---( Array with 3 element(s): )---\r
+--> State of array before loop:\r
+array(3) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(3) "v.2"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=1; $v=v.1\r
+     iteration 2:  $k=2; $v=v.2\r
+--> State of array after loop:\r
+array(0) {\r
+}\r
+\r
+---( Array with 4 element(s): )---\r
+--> State of array before loop:\r
+array(4) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(3) "v.2"\r
+  [3]=>\r
+  string(3) "v.3"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=1; $v=v.1\r
+     iteration 2:  $k=2; $v=v.2\r
+     iteration 3:  $k=3; $v=v.3\r
+--> State of array after loop:\r
+array(0) {\r
+}\r
+\r
+\r
+\r
+Adding elements to the end of an unreferenced array, using &$value.\r
+---( Array with 1 element(s): )---\r
+--> State of array before loop:\r
+array(1) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+--> State of array after loop:\r
+array(2) {\r
+  [0]=>\r
+  &string(3) "v.0"\r
+  [1]=>\r
+  string(5) "new.0"\r
+}\r
+\r
+---( Array with 2 element(s): )---\r
+--> State of array before loop:\r
+array(2) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=1; $v=v.1\r
+     iteration 2:  $k=2; $v=new.0\r
+     iteration 3:  $k=3; $v=new.1\r
+     iteration 4:  $k=4; $v=new.2\r
+     iteration 5:  $k=5; $v=new.3\r
+  ** Stuck in a loop! **\r
+--> State of array after loop:\r
+array(8) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(5) "new.0"\r
+  [3]=>\r
+  string(5) "new.1"\r
+  [4]=>\r
+  string(5) "new.2"\r
+  [5]=>\r
+  &string(5) "new.3"\r
+  [6]=>\r
+  string(5) "new.4"\r
+  [7]=>\r
+  string(5) "new.5"\r
+}\r
+\r
+---( Array with 3 element(s): )---\r
+--> State of array before loop:\r
+array(3) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(3) "v.2"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=1; $v=v.1\r
+     iteration 2:  $k=2; $v=v.2\r
+     iteration 3:  $k=3; $v=new.0\r
+     iteration 4:  $k=4; $v=new.1\r
+     iteration 5:  $k=5; $v=new.2\r
+  ** Stuck in a loop! **\r
+--> State of array after loop:\r
+array(9) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(3) "v.2"\r
+  [3]=>\r
+  string(5) "new.0"\r
+  [4]=>\r
+  string(5) "new.1"\r
+  [5]=>\r
+  &string(5) "new.2"\r
+  [6]=>\r
+  string(5) "new.3"\r
+  [7]=>\r
+  string(5) "new.4"\r
+  [8]=>\r
+  string(5) "new.5"\r
+}\r
+\r
+---( Array with 4 element(s): )---\r
+--> State of array before loop:\r
+array(4) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(3) "v.2"\r
+  [3]=>\r
+  string(3) "v.3"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=1; $v=v.1\r
+     iteration 2:  $k=2; $v=v.2\r
+     iteration 3:  $k=3; $v=v.3\r
+     iteration 4:  $k=4; $v=new.0\r
+     iteration 5:  $k=5; $v=new.1\r
+  ** Stuck in a loop! **\r
+--> State of array after loop:\r
+array(10) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(3) "v.2"\r
+  [3]=>\r
+  string(3) "v.3"\r
+  [4]=>\r
+  string(5) "new.0"\r
+  [5]=>\r
+  &string(5) "new.1"\r
+  [6]=>\r
+  string(5) "new.2"\r
+  [7]=>\r
+  string(5) "new.3"\r
+  [8]=>\r
+  string(5) "new.4"\r
+  [9]=>\r
+  string(5) "new.5"\r
+}\r
+\r
+\r
+\r
+Adding elements to the start of an unreferenced array, using &$value.\r
+---( Array with 1 element(s): )---\r
+--> State of array before loop:\r
+array(1) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+--> State of array after loop:\r
+array(2) {\r
+  [0]=>\r
+  string(5) "new.0"\r
+  [1]=>\r
+  &string(3) "v.0"\r
+}\r
+\r
+---( Array with 2 element(s): )---\r
+--> State of array before loop:\r
+array(2) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=0; $v=new.0\r
+     iteration 2:  $k=0; $v=new.1\r
+     iteration 3:  $k=0; $v=new.2\r
+     iteration 4:  $k=0; $v=new.3\r
+     iteration 5:  $k=0; $v=new.4\r
+  ** Stuck in a loop! **\r
+--> State of array after loop:\r
+array(8) {\r
+  [0]=>\r
+  string(5) "new.5"\r
+  [1]=>\r
+  &string(5) "new.4"\r
+  [2]=>\r
+  string(5) "new.3"\r
+  [3]=>\r
+  string(5) "new.2"\r
+  [4]=>\r
+  string(5) "new.1"\r
+  [5]=>\r
+  string(5) "new.0"\r
+  [6]=>\r
+  string(3) "v.0"\r
+  [7]=>\r
+  string(3) "v.1"\r
+}\r
+\r
+---( Array with 3 element(s): )---\r
+--> State of array before loop:\r
+array(3) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(3) "v.2"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=0; $v=new.0\r
+     iteration 2:  $k=0; $v=new.1\r
+     iteration 3:  $k=0; $v=new.2\r
+     iteration 4:  $k=0; $v=new.3\r
+     iteration 5:  $k=0; $v=new.4\r
+  ** Stuck in a loop! **\r
+--> State of array after loop:\r
+array(9) {\r
+  [0]=>\r
+  string(5) "new.5"\r
+  [1]=>\r
+  &string(5) "new.4"\r
+  [2]=>\r
+  string(5) "new.3"\r
+  [3]=>\r
+  string(5) "new.2"\r
+  [4]=>\r
+  string(5) "new.1"\r
+  [5]=>\r
+  string(5) "new.0"\r
+  [6]=>\r
+  string(3) "v.0"\r
+  [7]=>\r
+  string(3) "v.1"\r
+  [8]=>\r
+  string(3) "v.2"\r
+}\r
+\r
+---( Array with 4 element(s): )---\r
+--> State of array before loop:\r
+array(4) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(3) "v.2"\r
+  [3]=>\r
+  string(3) "v.3"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=0; $v=new.0\r
+     iteration 2:  $k=0; $v=new.1\r
+     iteration 3:  $k=0; $v=new.2\r
+     iteration 4:  $k=0; $v=new.3\r
+     iteration 5:  $k=0; $v=new.4\r
+  ** Stuck in a loop! **\r
+--> State of array after loop:\r
+array(10) {\r
+  [0]=>\r
+  string(5) "new.5"\r
+  [1]=>\r
+  &string(5) "new.4"\r
+  [2]=>\r
+  string(5) "new.3"\r
+  [3]=>\r
+  string(5) "new.2"\r
+  [4]=>\r
+  string(5) "new.1"\r
+  [5]=>\r
+  string(5) "new.0"\r
+  [6]=>\r
+  string(3) "v.0"\r
+  [7]=>\r
+  string(3) "v.1"\r
+  [8]=>\r
+  string(3) "v.2"\r
+  [9]=>\r
+  string(3) "v.3"\r
+}\r
diff --git a/tests/lang/foreachLoop.014.phpt b/tests/lang/foreachLoop.014.phpt
new file mode 100644 (file)
index 0000000..ab3c657
--- /dev/null
@@ -0,0 +1,556 @@
+--TEST--\r
+Directly modifying a REFERENCED array when foreach'ing over it.\r
+--FILE--\r
+<?php\r
+\r
+define('MAX_LOOPS',5);\r
+\r
+function withRefValue($elements, $transform) {\r
+       echo "\n---( Array with $elements element(s): )---\n";\r
+       //Build array:\r
+       for ($i=0; $i<$elements; $i++) {\r
+               $a[] = "v.$i";\r
+       }\r
+       $counter=0;\r
+       \r
+       $ref = &$a;\r
+       \r
+       echo "--> State of referenced array before loop:\n";\r
+       var_dump($a);\r
+       \r
+       echo "--> Do loop:\n";  \r
+       foreach ($a as $k=>$v) {\r
+               echo "     iteration $counter:  \$k=$k; \$v=$v\n";\r
+               eval($transform);\r
+               $counter++;\r
+               if ($counter>MAX_LOOPS) {\r
+                       echo "  ** Stuck in a loop! **\n";\r
+                       break;\r
+               }\r
+       }\r
+       \r
+       echo "--> State of array after loop:\n";\r
+       var_dump($a);\r
+}\r
+\r
+\r
+echo "\nPopping elements off end of a referenced array";\r
+$transform = 'array_pop($a);';\r
+withRefValue(1, $transform);\r
+withRefValue(2, $transform);\r
+withRefValue(3, $transform);\r
+withRefValue(4, $transform);\r
+\r
+echo "\n\n\nShift elements off start of a referenced array";\r
+$transform = 'array_shift($a);';\r
+withRefValue(1, $transform);\r
+withRefValue(2, $transform);\r
+withRefValue(3, $transform);\r
+withRefValue(4, $transform);\r
+\r
+echo "\n\n\nRemove current element of a referenced array";\r
+$transform = 'unset($a[$k]);';\r
+withRefValue(1, $transform);\r
+withRefValue(2, $transform);\r
+withRefValue(3, $transform);\r
+withRefValue(4, $transform);\r
+\r
+echo "\n\n\nAdding elements to the end of a referenced array";\r
+$transform = 'array_push($a, "new.$counter");';\r
+withRefValue(1, $transform);\r
+withRefValue(2, $transform);\r
+withRefValue(3, $transform);\r
+withRefValue(4, $transform);\r
+\r
+echo "\n\n\nAdding elements to the start of a referenced array";\r
+$transform = 'array_unshift($a, "new.$counter");';\r
+withRefValue(1, $transform);\r
+withRefValue(2, $transform);\r
+withRefValue(3, $transform);\r
+withRefValue(4, $transform);\r
+\r
+?>\r
+--EXPECTF--\r
+Popping elements off end of a referenced array\r
+---( Array with 1 element(s): )---\r
+--> State of referenced array before loop:\r
+array(1) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+--> State of array after loop:\r
+array(0) {\r
+}\r
+\r
+---( Array with 2 element(s): )---\r
+--> State of referenced array before loop:\r
+array(2) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=0; $v=v.0\r
+--> State of array after loop:\r
+array(0) {\r
+}\r
+\r
+---( Array with 3 element(s): )---\r
+--> State of referenced array before loop:\r
+array(3) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(3) "v.2"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=1; $v=v.1\r
+--> State of array after loop:\r
+array(1) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+}\r
+\r
+---( Array with 4 element(s): )---\r
+--> State of referenced array before loop:\r
+array(4) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(3) "v.2"\r
+  [3]=>\r
+  string(3) "v.3"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=1; $v=v.1\r
+     iteration 2:  $k=0; $v=v.0\r
+     iteration 3:  $k=0; $v=v.0\r
+--> State of array after loop:\r
+array(0) {\r
+}\r
+\r
+\r
+\r
+Shift elements off start of a referenced array\r
+---( Array with 1 element(s): )---\r
+--> State of referenced array before loop:\r
+array(1) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+--> State of array after loop:\r
+array(0) {\r
+}\r
+\r
+---( Array with 2 element(s): )---\r
+--> State of referenced array before loop:\r
+array(2) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=0; $v=v.1\r
+--> State of array after loop:\r
+array(0) {\r
+}\r
+\r
+---( Array with 3 element(s): )---\r
+--> State of referenced array before loop:\r
+array(3) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(3) "v.2"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=0; $v=v.1\r
+     iteration 2:  $k=0; $v=v.2\r
+--> State of array after loop:\r
+array(0) {\r
+}\r
+\r
+---( Array with 4 element(s): )---\r
+--> State of referenced array before loop:\r
+array(4) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(3) "v.2"\r
+  [3]=>\r
+  string(3) "v.3"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=0; $v=v.1\r
+     iteration 2:  $k=0; $v=v.2\r
+     iteration 3:  $k=0; $v=v.3\r
+--> State of array after loop:\r
+array(0) {\r
+}\r
+\r
+\r
+\r
+Remove current element of a referenced array\r
+---( Array with 1 element(s): )---\r
+--> State of referenced array before loop:\r
+array(1) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+--> State of array after loop:\r
+array(0) {\r
+}\r
+\r
+---( Array with 2 element(s): )---\r
+--> State of referenced array before loop:\r
+array(2) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=1; $v=v.1\r
+--> State of array after loop:\r
+array(0) {\r
+}\r
+\r
+---( Array with 3 element(s): )---\r
+--> State of referenced array before loop:\r
+array(3) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(3) "v.2"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=1; $v=v.1\r
+     iteration 2:  $k=2; $v=v.2\r
+--> State of array after loop:\r
+array(0) {\r
+}\r
+\r
+---( Array with 4 element(s): )---\r
+--> State of referenced array before loop:\r
+array(4) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(3) "v.2"\r
+  [3]=>\r
+  string(3) "v.3"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=1; $v=v.1\r
+     iteration 2:  $k=2; $v=v.2\r
+     iteration 3:  $k=3; $v=v.3\r
+--> State of array after loop:\r
+array(0) {\r
+}\r
+\r
+\r
+\r
+Adding elements to the end of a referenced array\r
+---( Array with 1 element(s): )---\r
+--> State of referenced array before loop:\r
+array(1) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+--> State of array after loop:\r
+array(2) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(5) "new.0"\r
+}\r
+\r
+---( Array with 2 element(s): )---\r
+--> State of referenced array before loop:\r
+array(2) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=1; $v=v.1\r
+     iteration 2:  $k=2; $v=new.0\r
+     iteration 3:  $k=3; $v=new.1\r
+     iteration 4:  $k=4; $v=new.2\r
+     iteration 5:  $k=5; $v=new.3\r
+  ** Stuck in a loop! **\r
+--> State of array after loop:\r
+array(8) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(5) "new.0"\r
+  [3]=>\r
+  string(5) "new.1"\r
+  [4]=>\r
+  string(5) "new.2"\r
+  [5]=>\r
+  string(5) "new.3"\r
+  [6]=>\r
+  string(5) "new.4"\r
+  [7]=>\r
+  string(5) "new.5"\r
+}\r
+\r
+---( Array with 3 element(s): )---\r
+--> State of referenced array before loop:\r
+array(3) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(3) "v.2"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=1; $v=v.1\r
+     iteration 2:  $k=2; $v=v.2\r
+     iteration 3:  $k=3; $v=new.0\r
+     iteration 4:  $k=4; $v=new.1\r
+     iteration 5:  $k=5; $v=new.2\r
+  ** Stuck in a loop! **\r
+--> State of array after loop:\r
+array(9) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(3) "v.2"\r
+  [3]=>\r
+  string(5) "new.0"\r
+  [4]=>\r
+  string(5) "new.1"\r
+  [5]=>\r
+  string(5) "new.2"\r
+  [6]=>\r
+  string(5) "new.3"\r
+  [7]=>\r
+  string(5) "new.4"\r
+  [8]=>\r
+  string(5) "new.5"\r
+}\r
+\r
+---( Array with 4 element(s): )---\r
+--> State of referenced array before loop:\r
+array(4) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(3) "v.2"\r
+  [3]=>\r
+  string(3) "v.3"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=1; $v=v.1\r
+     iteration 2:  $k=2; $v=v.2\r
+     iteration 3:  $k=3; $v=v.3\r
+     iteration 4:  $k=4; $v=new.0\r
+     iteration 5:  $k=5; $v=new.1\r
+  ** Stuck in a loop! **\r
+--> State of array after loop:\r
+array(10) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(3) "v.2"\r
+  [3]=>\r
+  string(3) "v.3"\r
+  [4]=>\r
+  string(5) "new.0"\r
+  [5]=>\r
+  string(5) "new.1"\r
+  [6]=>\r
+  string(5) "new.2"\r
+  [7]=>\r
+  string(5) "new.3"\r
+  [8]=>\r
+  string(5) "new.4"\r
+  [9]=>\r
+  string(5) "new.5"\r
+}\r
+\r
+\r
+\r
+Adding elements to the start of a referenced array\r
+---( Array with 1 element(s): )---\r
+--> State of referenced array before loop:\r
+array(1) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+--> State of array after loop:\r
+array(2) {\r
+  [0]=>\r
+  string(5) "new.0"\r
+  [1]=>\r
+  string(3) "v.0"\r
+}\r
+\r
+---( Array with 2 element(s): )---\r
+--> State of referenced array before loop:\r
+array(2) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=0; $v=new.0\r
+     iteration 2:  $k=0; $v=new.1\r
+     iteration 3:  $k=0; $v=new.2\r
+     iteration 4:  $k=0; $v=new.3\r
+     iteration 5:  $k=0; $v=new.4\r
+  ** Stuck in a loop! **\r
+--> State of array after loop:\r
+array(8) {\r
+  [0]=>\r
+  string(5) "new.5"\r
+  [1]=>\r
+  string(5) "new.4"\r
+  [2]=>\r
+  string(5) "new.3"\r
+  [3]=>\r
+  string(5) "new.2"\r
+  [4]=>\r
+  string(5) "new.1"\r
+  [5]=>\r
+  string(5) "new.0"\r
+  [6]=>\r
+  string(3) "v.0"\r
+  [7]=>\r
+  string(3) "v.1"\r
+}\r
+\r
+---( Array with 3 element(s): )---\r
+--> State of referenced array before loop:\r
+array(3) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(3) "v.2"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=0; $v=new.0\r
+     iteration 2:  $k=0; $v=new.1\r
+     iteration 3:  $k=0; $v=new.2\r
+     iteration 4:  $k=0; $v=new.3\r
+     iteration 5:  $k=0; $v=new.4\r
+  ** Stuck in a loop! **\r
+--> State of array after loop:\r
+array(9) {\r
+  [0]=>\r
+  string(5) "new.5"\r
+  [1]=>\r
+  string(5) "new.4"\r
+  [2]=>\r
+  string(5) "new.3"\r
+  [3]=>\r
+  string(5) "new.2"\r
+  [4]=>\r
+  string(5) "new.1"\r
+  [5]=>\r
+  string(5) "new.0"\r
+  [6]=>\r
+  string(3) "v.0"\r
+  [7]=>\r
+  string(3) "v.1"\r
+  [8]=>\r
+  string(3) "v.2"\r
+}\r
+\r
+---( Array with 4 element(s): )---\r
+--> State of referenced array before loop:\r
+array(4) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(3) "v.2"\r
+  [3]=>\r
+  string(3) "v.3"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=0; $v=new.0\r
+     iteration 2:  $k=0; $v=new.1\r
+     iteration 3:  $k=0; $v=new.2\r
+     iteration 4:  $k=0; $v=new.3\r
+     iteration 5:  $k=0; $v=new.4\r
+  ** Stuck in a loop! **\r
+--> State of array after loop:\r
+array(10) {\r
+  [0]=>\r
+  string(5) "new.5"\r
+  [1]=>\r
+  string(5) "new.4"\r
+  [2]=>\r
+  string(5) "new.3"\r
+  [3]=>\r
+  string(5) "new.2"\r
+  [4]=>\r
+  string(5) "new.1"\r
+  [5]=>\r
+  string(5) "new.0"\r
+  [6]=>\r
+  string(3) "v.0"\r
+  [7]=>\r
+  string(3) "v.1"\r
+  [8]=>\r
+  string(3) "v.2"\r
+  [9]=>\r
+  string(3) "v.3"\r
+}
\ No newline at end of file
diff --git a/tests/lang/foreachLoop.015.phpt b/tests/lang/foreachLoop.015.phpt
new file mode 100644 (file)
index 0000000..dfba159
--- /dev/null
@@ -0,0 +1,557 @@
+--TEST--\r
+Directly modifying a REFERENCED array when foreach'ing over it while using &$value syntax.\r
+--FILE--\r
+<?php\r
+\r
+define('MAX_LOOPS',5);\r
+\r
+function withRefValue($elements, $transform) {\r
+       echo "\n---( Array with $elements element(s): )---\n";\r
+       //Build array:\r
+       for ($i=0; $i<$elements; $i++) {\r
+               $a[] = "v.$i";\r
+       }\r
+       $counter=0;\r
+       \r
+       $ref = &$a;\r
+       \r
+       echo "--> State of referenced array before loop:\n";\r
+       var_dump($a);\r
+       \r
+       echo "--> Do loop:\n";  \r
+       foreach ($a as $k=>&$v) {\r
+               echo "     iteration $counter:  \$k=$k; \$v=$v\n";\r
+               eval($transform);\r
+               $counter++;\r
+               if ($counter>MAX_LOOPS) {\r
+                       echo "  ** Stuck in a loop! **\n";\r
+                       break;\r
+               }\r
+       }\r
+       \r
+       echo "--> State of array after loop:\n";\r
+       var_dump($a);\r
+}\r
+\r
+\r
+echo "\nPopping elements off end of a referenced array, using &\$value";\r
+$transform = 'array_pop($a);';\r
+withRefValue(1, $transform);\r
+withRefValue(2, $transform);\r
+withRefValue(3, $transform);\r
+withRefValue(4, $transform);\r
+\r
+echo "\n\n\nShift elements off start of a referenced array, using &\$value";\r
+$transform = 'array_shift($a);';\r
+withRefValue(1, $transform);\r
+withRefValue(2, $transform);\r
+withRefValue(3, $transform);\r
+withRefValue(4, $transform);\r
+\r
+echo "\n\n\nRemove current element of a referenced array, using &\$value";\r
+$transform = 'unset($a[$k]);';\r
+withRefValue(1, $transform);\r
+withRefValue(2, $transform);\r
+withRefValue(3, $transform);\r
+withRefValue(4, $transform);\r
+\r
+echo "\n\n\nAdding elements to the end of a referenced array, using &\$value";\r
+$transform = 'array_push($a, "new.$counter");';\r
+withRefValue(1, $transform);\r
+withRefValue(2, $transform);\r
+withRefValue(3, $transform);\r
+withRefValue(4, $transform);\r
+\r
+echo "\n\n\nAdding elements to the start of a referenced array, using &\$value";\r
+$transform = 'array_unshift($a, "new.$counter");';\r
+withRefValue(1, $transform);\r
+withRefValue(2, $transform);\r
+withRefValue(3, $transform);\r
+withRefValue(4, $transform);\r
+\r
+?>\r
+--EXPECTF--\r
+\r
+Popping elements off end of a referenced array, using &$value\r
+---( Array with 1 element(s): )---\r
+--> State of referenced array before loop:\r
+array(1) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+--> State of array after loop:\r
+array(0) {\r
+}\r
+\r
+---( Array with 2 element(s): )---\r
+--> State of referenced array before loop:\r
+array(2) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=0; $v=v.0\r
+--> State of array after loop:\r
+array(0) {\r
+}\r
+\r
+---( Array with 3 element(s): )---\r
+--> State of referenced array before loop:\r
+array(3) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(3) "v.2"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=1; $v=v.1\r
+--> State of array after loop:\r
+array(1) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+}\r
+\r
+---( Array with 4 element(s): )---\r
+--> State of referenced array before loop:\r
+array(4) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(3) "v.2"\r
+  [3]=>\r
+  string(3) "v.3"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=1; $v=v.1\r
+     iteration 2:  $k=0; $v=v.0\r
+     iteration 3:  $k=0; $v=v.0\r
+--> State of array after loop:\r
+array(0) {\r
+}\r
+\r
+\r
+\r
+Shift elements off start of a referenced array, using &$value\r
+---( Array with 1 element(s): )---\r
+--> State of referenced array before loop:\r
+array(1) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+--> State of array after loop:\r
+array(0) {\r
+}\r
+\r
+---( Array with 2 element(s): )---\r
+--> State of referenced array before loop:\r
+array(2) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=0; $v=v.1\r
+--> State of array after loop:\r
+array(0) {\r
+}\r
+\r
+---( Array with 3 element(s): )---\r
+--> State of referenced array before loop:\r
+array(3) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(3) "v.2"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=0; $v=v.1\r
+     iteration 2:  $k=0; $v=v.2\r
+--> State of array after loop:\r
+array(0) {\r
+}\r
+\r
+---( Array with 4 element(s): )---\r
+--> State of referenced array before loop:\r
+array(4) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(3) "v.2"\r
+  [3]=>\r
+  string(3) "v.3"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=0; $v=v.1\r
+     iteration 2:  $k=0; $v=v.2\r
+     iteration 3:  $k=0; $v=v.3\r
+--> State of array after loop:\r
+array(0) {\r
+}\r
+\r
+\r
+\r
+Remove current element of a referenced array, using &$value\r
+---( Array with 1 element(s): )---\r
+--> State of referenced array before loop:\r
+array(1) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+--> State of array after loop:\r
+array(0) {\r
+}\r
+\r
+---( Array with 2 element(s): )---\r
+--> State of referenced array before loop:\r
+array(2) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=1; $v=v.1\r
+--> State of array after loop:\r
+array(0) {\r
+}\r
+\r
+---( Array with 3 element(s): )---\r
+--> State of referenced array before loop:\r
+array(3) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(3) "v.2"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=1; $v=v.1\r
+     iteration 2:  $k=2; $v=v.2\r
+--> State of array after loop:\r
+array(0) {\r
+}\r
+\r
+---( Array with 4 element(s): )---\r
+--> State of referenced array before loop:\r
+array(4) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(3) "v.2"\r
+  [3]=>\r
+  string(3) "v.3"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=1; $v=v.1\r
+     iteration 2:  $k=2; $v=v.2\r
+     iteration 3:  $k=3; $v=v.3\r
+--> State of array after loop:\r
+array(0) {\r
+}\r
+\r
+\r
+\r
+Adding elements to the end of a referenced array, using &$value\r
+---( Array with 1 element(s): )---\r
+--> State of referenced array before loop:\r
+array(1) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+--> State of array after loop:\r
+array(2) {\r
+  [0]=>\r
+  &string(3) "v.0"\r
+  [1]=>\r
+  string(5) "new.0"\r
+}\r
+\r
+---( Array with 2 element(s): )---\r
+--> State of referenced array before loop:\r
+array(2) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=1; $v=v.1\r
+     iteration 2:  $k=2; $v=new.0\r
+     iteration 3:  $k=3; $v=new.1\r
+     iteration 4:  $k=4; $v=new.2\r
+     iteration 5:  $k=5; $v=new.3\r
+  ** Stuck in a loop! **\r
+--> State of array after loop:\r
+array(8) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(5) "new.0"\r
+  [3]=>\r
+  string(5) "new.1"\r
+  [4]=>\r
+  string(5) "new.2"\r
+  [5]=>\r
+  &string(5) "new.3"\r
+  [6]=>\r
+  string(5) "new.4"\r
+  [7]=>\r
+  string(5) "new.5"\r
+}\r
+\r
+---( Array with 3 element(s): )---\r
+--> State of referenced array before loop:\r
+array(3) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(3) "v.2"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=1; $v=v.1\r
+     iteration 2:  $k=2; $v=v.2\r
+     iteration 3:  $k=3; $v=new.0\r
+     iteration 4:  $k=4; $v=new.1\r
+     iteration 5:  $k=5; $v=new.2\r
+  ** Stuck in a loop! **\r
+--> State of array after loop:\r
+array(9) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(3) "v.2"\r
+  [3]=>\r
+  string(5) "new.0"\r
+  [4]=>\r
+  string(5) "new.1"\r
+  [5]=>\r
+  &string(5) "new.2"\r
+  [6]=>\r
+  string(5) "new.3"\r
+  [7]=>\r
+  string(5) "new.4"\r
+  [8]=>\r
+  string(5) "new.5"\r
+}\r
+\r
+---( Array with 4 element(s): )---\r
+--> State of referenced array before loop:\r
+array(4) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(3) "v.2"\r
+  [3]=>\r
+  string(3) "v.3"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=1; $v=v.1\r
+     iteration 2:  $k=2; $v=v.2\r
+     iteration 3:  $k=3; $v=v.3\r
+     iteration 4:  $k=4; $v=new.0\r
+     iteration 5:  $k=5; $v=new.1\r
+  ** Stuck in a loop! **\r
+--> State of array after loop:\r
+array(10) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(3) "v.2"\r
+  [3]=>\r
+  string(3) "v.3"\r
+  [4]=>\r
+  string(5) "new.0"\r
+  [5]=>\r
+  &string(5) "new.1"\r
+  [6]=>\r
+  string(5) "new.2"\r
+  [7]=>\r
+  string(5) "new.3"\r
+  [8]=>\r
+  string(5) "new.4"\r
+  [9]=>\r
+  string(5) "new.5"\r
+}\r
+\r
+\r
+\r
+Adding elements to the start of a referenced array, using &$value\r
+---( Array with 1 element(s): )---\r
+--> State of referenced array before loop:\r
+array(1) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+--> State of array after loop:\r
+array(2) {\r
+  [0]=>\r
+  string(5) "new.0"\r
+  [1]=>\r
+  &string(3) "v.0"\r
+}\r
+\r
+---( Array with 2 element(s): )---\r
+--> State of referenced array before loop:\r
+array(2) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=0; $v=new.0\r
+     iteration 2:  $k=0; $v=new.1\r
+     iteration 3:  $k=0; $v=new.2\r
+     iteration 4:  $k=0; $v=new.3\r
+     iteration 5:  $k=0; $v=new.4\r
+  ** Stuck in a loop! **\r
+--> State of array after loop:\r
+array(8) {\r
+  [0]=>\r
+  string(5) "new.5"\r
+  [1]=>\r
+  &string(5) "new.4"\r
+  [2]=>\r
+  string(5) "new.3"\r
+  [3]=>\r
+  string(5) "new.2"\r
+  [4]=>\r
+  string(5) "new.1"\r
+  [5]=>\r
+  string(5) "new.0"\r
+  [6]=>\r
+  string(3) "v.0"\r
+  [7]=>\r
+  string(3) "v.1"\r
+}\r
+\r
+---( Array with 3 element(s): )---\r
+--> State of referenced array before loop:\r
+array(3) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(3) "v.2"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=0; $v=new.0\r
+     iteration 2:  $k=0; $v=new.1\r
+     iteration 3:  $k=0; $v=new.2\r
+     iteration 4:  $k=0; $v=new.3\r
+     iteration 5:  $k=0; $v=new.4\r
+  ** Stuck in a loop! **\r
+--> State of array after loop:\r
+array(9) {\r
+  [0]=>\r
+  string(5) "new.5"\r
+  [1]=>\r
+  &string(5) "new.4"\r
+  [2]=>\r
+  string(5) "new.3"\r
+  [3]=>\r
+  string(5) "new.2"\r
+  [4]=>\r
+  string(5) "new.1"\r
+  [5]=>\r
+  string(5) "new.0"\r
+  [6]=>\r
+  string(3) "v.0"\r
+  [7]=>\r
+  string(3) "v.1"\r
+  [8]=>\r
+  string(3) "v.2"\r
+}\r
+\r
+---( Array with 4 element(s): )---\r
+--> State of referenced array before loop:\r
+array(4) {\r
+  [0]=>\r
+  string(3) "v.0"\r
+  [1]=>\r
+  string(3) "v.1"\r
+  [2]=>\r
+  string(3) "v.2"\r
+  [3]=>\r
+  string(3) "v.3"\r
+}\r
+--> Do loop:\r
+     iteration 0:  $k=0; $v=v.0\r
+     iteration 1:  $k=0; $v=new.0\r
+     iteration 2:  $k=0; $v=new.1\r
+     iteration 3:  $k=0; $v=new.2\r
+     iteration 4:  $k=0; $v=new.3\r
+     iteration 5:  $k=0; $v=new.4\r
+  ** Stuck in a loop! **\r
+--> State of array after loop:\r
+array(10) {\r
+  [0]=>\r
+  string(5) "new.5"\r
+  [1]=>\r
+  &string(5) "new.4"\r
+  [2]=>\r
+  string(5) "new.3"\r
+  [3]=>\r
+  string(5) "new.2"\r
+  [4]=>\r
+  string(5) "new.1"\r
+  [5]=>\r
+  string(5) "new.0"\r
+  [6]=>\r
+  string(3) "v.0"\r
+  [7]=>\r
+  string(3) "v.1"\r
+  [8]=>\r
+  string(3) "v.2"\r
+  [9]=>\r
+  string(3) "v.3"\r
+}\r
diff --git a/tests/lang/foreachLoop.016.phpt b/tests/lang/foreachLoop.016.phpt
new file mode 100644 (file)
index 0000000..dc31a50
--- /dev/null
@@ -0,0 +1,198 @@
+--TEST--\r
+Ensure foreach splits the iterated entity from its cow reference set, for all sorts of iterated entities.\r
+--FILE--\r
+<?php\r
+  error_reporting(E_ALL & ~E_STRICT);\r
+\r
+  echo "\n" . '$a' . "\n";\r
+  $b = $a = array('original');\r
+  foreach($a as $k=>&$v) {\r
+        $v = 'changed';\r
+  }\r
+  var_dump($b);\r
+  unset($a, $b);\r
+  \r
+  echo "\n" . '${\'a\'}' . "\n";\r
+  $b = $a = array('original');\r
+  foreach(${'a'} as $k=>&$v) {\r
+        $v = 'changed';\r
+  }\r
+  var_dump($b);\r
+  unset($a, $b);\r
+  \r
+  echo "\n" . '$$a' . "\n";\r
+  $a = 'blah';\r
+  $$a = array('original');\r
+  $b = $$a;\r
+  foreach($$a as $k=>&$v) {\r
+        $v = 'changed';\r
+  }\r
+  var_dump($b);\r
+  unset($a, $b);\r
+  \r
+  echo "\n" . '$a[0]' . "\n";\r
+  $b = $a[0] = array('original');\r
+  foreach($a[0] as $k=>&$v) {\r
+        $v = 'changed';\r
+  }\r
+  var_dump($b);\r
+  unset($a, $b);\r
+  \r
+  echo "\n" . '$a[0][0]' . "\n";\r
+  $b = $a[0][0] = array('original');\r
+  foreach($a[0][0] as $k=>&$v) {\r
+        $v = 'changed';\r
+  }\r
+  var_dump($b);\r
+  unset($a, $b);\r
+  \r
+  echo "\n" . '$a->b' . "\n";\r
+  $b = $a->b = array('original');\r
+  foreach($a->b as $k=>&$v) {\r
+        $v = 'changed';\r
+  }\r
+  var_dump($b);\r
+  unset($a, $b);\r
+  \r
+  echo "\n" . '$a->b->c' . "\n";\r
+  $b = $a->b->c = array('original');\r
+  foreach($a->b as $k=>&$v) {\r
+        $v = 'changed';\r
+  }\r
+  var_dump($b);\r
+  unset($a, $b);\r
+  \r
+  echo "\n" . '$a->b[0]' . "\n";\r
+  $b = $a->b[0] = array('original');\r
+  foreach($a->b[0] as $k=>&$v) {\r
+        $v = 'changed';\r
+  }\r
+  var_dump($b);\r
+  unset($a, $b);\r
+  \r
+  echo "\n" . '$a->b[0][0]' . "\n";\r
+  $b = $a->b[0][0] = array('original');\r
+  foreach($a->b[0][0] as $k=>&$v) {\r
+        $v = 'changed';\r
+  }\r
+  var_dump($b);\r
+  unset($a, $b);\r
+  \r
+  echo "\n" . '$a->b[0]->c' . "\n";\r
+  $b = $a->b[0]->c = array('original');\r
+  foreach($a->b[0]->c as $k=>&$v) {\r
+        $v = 'changed';\r
+  }\r
+  var_dump($b);\r
+  unset($a, $b);\r
+  \r
+  class C {\r
+       public static $a;\r
+  }\r
+  \r
+  echo "\n" . 'C::$a' . "\n";\r
+  C::$a = array('original');\r
+  $b = C::$a;\r
+  foreach(C::$a as $k=>&$v) {\r
+        $v = 'changed';\r
+  }\r
+  var_dump($b);\r
+  unset($a, $b);\r
+  \r
+  echo "\n" . 'C::$a[0]' . "\n";\r
+  C::$a[0] = array('original');\r
+  $b = C::$a[0];\r
+  foreach(C::$a[0] as $k=>&$v) {\r
+        $v = 'changed';\r
+  }\r
+  var_dump($b);\r
+  unset(C::$a[0], $b);\r
+  \r
+  echo "\n" . 'C::$a[0]->b' . "\n";\r
+  C::$a[0]->b = array('original');\r
+  $b = C::$a[0]->b;\r
+  foreach(C::$a[0]->b as $k=>&$v) {\r
+        $v = 'changed';\r
+  }\r
+  var_dump($b);\r
+  unset(C::$a[0]->b, $b);\r
+?>\r
+--EXPECTF--\r
+\r
+$a\r
+array(1) {\r
+  [0]=>\r
+  string(8) "original"\r
+}\r
+\r
+${'a'}\r
+array(1) {\r
+  [0]=>\r
+  string(8) "original"\r
+}\r
+\r
+$$a\r
+array(1) {\r
+  [0]=>\r
+  string(8) "original"\r
+}\r
+\r
+$a[0]\r
+array(1) {\r
+  [0]=>\r
+  string(8) "original"\r
+}\r
+\r
+$a[0][0]\r
+array(1) {\r
+  [0]=>\r
+  string(8) "original"\r
+}\r
+\r
+$a->b\r
+array(1) {\r
+  [0]=>\r
+  string(8) "original"\r
+}\r
+\r
+$a->b->c\r
+array(1) {\r
+  [0]=>\r
+  string(8) "original"\r
+}\r
+\r
+$a->b[0]\r
+array(1) {\r
+  [0]=>\r
+  string(8) "original"\r
+}\r
+\r
+$a->b[0][0]\r
+array(1) {\r
+  [0]=>\r
+  string(8) "original"\r
+}\r
+\r
+$a->b[0]->c\r
+array(1) {\r
+  [0]=>\r
+  string(8) "original"\r
+}\r
+\r
+C::$a\r
+array(1) {\r
+  [0]=>\r
+  string(8) "original"\r
+}\r
+\r
+C::$a[0]\r
+array(1) {\r
+  [0]=>\r
+  string(8) "original"\r
+}\r
+\r
+C::$a[0]->b\r
+array(1) {\r
+  [0]=>\r
+  string(8) "original"\r
+}
\ No newline at end of file
diff --git a/tests/lang/foreachLoop.017.phpt b/tests/lang/foreachLoop.017.phpt
new file mode 100644 (file)
index 0000000..3d2618e
--- /dev/null
@@ -0,0 +1,11 @@
+--TEST--\r
+Ensure foreach works with arrays with Binary keys.\r
+--FILE--\r
+<?php\r
+$a = array ( "\x90" => 10 );\r
+foreach ($a as $val=>$key) echo $key;\r
+echo "\nDone\n";\r
+?> \r
+--EXPECTF--\r
+10\r
+Done
\ No newline at end of file