mirror of
https://github.com/php/php-src.git
synced 2024-11-23 18:04:36 +08:00
Remove reference restrictions from foreach
foreach only allowed variables to be traversed by reference. This never really made sense because a) Expressions like array(&$a, &$b) can be meaningfully iterated by-ref b) Function calls can return by-ref (so they can also be meaningfully iterated) c) Iterators could at least in theory also be iterated by-ref (not sure if any iterator makes use of this) With by-ref generators the restriction makes even less sense, so I removed it altogether.
This commit is contained in:
parent
80748631aa
commit
de80e3ce4b
@ -1,12 +0,0 @@
|
||||
--TEST--
|
||||
errmsg: cannot create references to temp array
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
foreach (array(1,2,3) as $k=>&$v) {
|
||||
}
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Cannot create references to elements of a temporary array expression in %s on line %d
|
18
Zend/tests/foreach_temp_array_expr_with_refs.phpt
Normal file
18
Zend/tests/foreach_temp_array_expr_with_refs.phpt
Normal file
@ -0,0 +1,18 @@
|
||||
--TEST--
|
||||
Temporary array expressions can be iterated by reference
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$a = 'a';
|
||||
$b = 'b';
|
||||
|
||||
foreach ([&$a, &$b] as &$value) {
|
||||
$value .= '-foo';
|
||||
}
|
||||
|
||||
var_dump($a, $b);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
string(5) "a-foo"
|
||||
string(5) "b-foo"
|
@ -9,24 +9,34 @@ function &iter(array &$array) {
|
||||
}
|
||||
}
|
||||
|
||||
$array = [1, 2, 3, 4, 5];
|
||||
$array = [1, 2, 3];
|
||||
$iter = iter($array);
|
||||
foreach ($iter as &$value) {
|
||||
$value *= -1;
|
||||
}
|
||||
var_dump($array);
|
||||
|
||||
$array = [1, 2, 3];
|
||||
foreach (iter($array) as &$value) {
|
||||
$value *= -1;
|
||||
}
|
||||
var_dump($array);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
array(5) {
|
||||
array(3) {
|
||||
[0]=>
|
||||
int(-1)
|
||||
[1]=>
|
||||
int(-2)
|
||||
[2]=>
|
||||
int(-3)
|
||||
[3]=>
|
||||
int(-4)
|
||||
[4]=>
|
||||
&int(-5)
|
||||
&int(-3)
|
||||
}
|
||||
array(3) {
|
||||
[0]=>
|
||||
int(-1)
|
||||
[1]=>
|
||||
int(-2)
|
||||
[2]=>
|
||||
&int(-3)
|
||||
}
|
||||
|
@ -6317,9 +6317,7 @@ void zend_do_foreach_cont(znode *foreach_token, const znode *open_brackets_token
|
||||
|
||||
if (value->EA & ZEND_PARSED_REFERENCE_VARIABLE) {
|
||||
assign_by_ref = 1;
|
||||
if (!(opline-1)->extended_value) {
|
||||
zend_error(E_COMPILE_ERROR, "Cannot create references to elements of a temporary array expression");
|
||||
}
|
||||
|
||||
/* Mark extended_value for assign-by-reference */
|
||||
opline->extended_value |= ZEND_FE_FETCH_BYREF;
|
||||
CG(active_op_array)->opcodes[foreach_token->u.op.opline_num].extended_value |= ZEND_FE_RESET_REFERENCE;
|
||||
|
@ -312,7 +312,7 @@ unticked_statement:
|
||||
foreach_statement { zend_do_foreach_end(&$1, &$4 TSRMLS_CC); }
|
||||
| T_FOREACH '(' expr_without_variable T_AS
|
||||
{ zend_do_foreach_begin(&$1, &$2, &$3, &$4, 0 TSRMLS_CC); }
|
||||
variable foreach_optional_arg ')' { zend_check_writable_variable(&$6); zend_do_foreach_cont(&$1, &$2, &$4, &$6, &$7 TSRMLS_CC); }
|
||||
foreach_variable foreach_optional_arg ')' { zend_do_foreach_cont(&$1, &$2, &$4, &$6, &$7 TSRMLS_CC); }
|
||||
foreach_statement { zend_do_foreach_end(&$1, &$4 TSRMLS_CC); }
|
||||
| T_DECLARE { $1.u.op.opline_num = get_next_op_number(CG(active_op_array)); zend_do_declare_begin(TSRMLS_C); } '(' declare_list ')' declare_statement { zend_do_declare_end(&$1 TSRMLS_CC); }
|
||||
| ';' /* empty statement */
|
||||
|
@ -1,10 +0,0 @@
|
||||
--TEST--
|
||||
Foreach loop tests - error case: reference to constant array, with key.
|
||||
--FILE--
|
||||
<?php
|
||||
foreach (array(1,2) as $k=>&$v) {
|
||||
var_dump($v);
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Cannot create references to elements of a temporary array expression in %s on line 2
|
Loading…
Reference in New Issue
Block a user