php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #80161 Iterating on key/value with reference (&) has unexpected side effect
Submitted: 2020-09-29 15:43 UTC Modified: 2020-09-29 21:19 UTC
From: g dot passault at gmail dot com Assigned: cmb (profile)
Status: Not a bug Package: Arrays related
PHP Version: 7.4.10 OS: Linux (Ubuntu 18.04)
Private report: No CVE-ID: None
 [2020-09-29 15:43 UTC] g dot passault at gmail dot com
Description:
------------
For some reason, walking an array using keys and reference values (&), even without doing anything with it and then walking it has an influence if and only if the variable name is the same in both cases

Test script:
---------------
<?php

$array = [ 
    'x' => 1,
    'y' => 2,
    'z' => 3
];

// This useless walk has an effect on below walk
foreach ($array as &$item) {}

// This will show 1 2 2 instead of 1 2 3
// If you use another name for $item variable, it will show 1 2 3
foreach ($array as $item)
{
    echo $item."\n";
}


Expected result:
----------------
1
2
3

Actual result:
--------------
1
2
2

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2020-09-29 15:48 UTC] g dot passault at gmail dot com
Actually, I understand the reason why this behaves like that, since at the end of the first foreach loop $item is a reference to the last item in the array

However I'm not sure if assigning a value to a variable that is a reference through the "as" of a foreach is a good behaviour

This issue actually happened in a script I wrote and I was surprised with result, what I mean is that I can easily real life example why one would walk an array and change it, and then walk it again to read it, but not real life example of assigning a value with the first iteration of a loop through the "as" of foreach.
 [2020-09-29 15:50 UTC] fghghghgh at fgfgfg dot com
there is nothing unexpected, that's how references are working
http://schlueters.de/blog/archives/125-Do-not-use-PHP-references.html
 [2020-09-29 16:05 UTC] cmb@php.net
-Status: Open +Status: Not a bug -Assigned To: +Assigned To: cmb
 [2020-09-29 16:05 UTC] cmb@php.net
> However I'm not sure if assigning a value to a variable that is
> a reference through the "as" of a foreach is a good behaviour

There is nothing special about that assignment; it's a reference
assignment, if the variable is already a reference.  If you have
to use references in foreach loops, and you need the loop variable
later on, consider to unset() it after the loop.  See also the
warning on
<https://www.php.net/manual/en/control-structures.foreach.php>.
 [2020-09-29 21:02 UTC] g dot passault at gmail dot com
Imagine foreach($x as $y) would implicitely performs unset($y) beforehand, that would fix this broken behaviour, and what legitimate code would be impacted with such a change?
 [2020-09-29 21:19 UTC] cmb@php.net
It might be best to forward this feature request to the internals
mailing list[1], since this bugtracker isn't really suitable for
discussions.

[1] <https://www.php.net/mailing-lists.php#internals>
 
PHP Copyright © 2001-2021 The PHP Group
All rights reserved.
Last updated: Thu Dec 09 07:03:34 2021 UTC