php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #76349 Spoils the original array
Submitted: 2018-05-16 18:24 UTC Modified: 2018-05-16 19:50 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: arnowt at gmail dot com Assigned: peehaa (profile)
Status: Closed Package: *General Issues
PHP Version: Irrelevant OS: Linux
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: arnowt at gmail dot com
New email:
PHP Version: OS:

 

 [2018-05-16 18:24 UTC] arnowt at gmail dot com
Description:
------------
Портит исходный массив.
Проверял на версии v5.6 и v7.2

Test script:
---------------
$res=[1,2,3];
foreach($res as &$v){}
print_r($res);
foreach($res as $v){}
print_r($res);

Expected result:
----------------
Array
(
    [0] => 1
    [1] => 2
    [2] => 3
)
Array
(
    [0] => 1
    [1] => 2
    [2] => 3
)


Actual result:
--------------
Array
(
    [0] => 1
    [1] => 2
    [2] => 3
)
Array
(
    [0] => 1
    [1] => 2
    [2] => 2 //!!!!!!
)

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2018-05-16 19:11 UTC] spam2 at rhsoft dot net
just don't use references until you understand their implications and you are really sure you gain something - given the php engine has a copy-on-write paradigm there are very few cases
 [2018-05-16 19:14 UTC] spam2 at rhsoft dot net
to make it clear: you miss a unset between both loops, $v of the second one still points to the last item of the previous loop
 [2018-05-16 19:27 UTC] arnowt at gmail dot com
Я знаю что такое ссылки и использую их по назначению. Просто упростил пример.
В коде нет не единого присваивания, однако исходный массив изменяется.
Понятно что баг можно обойти, например если оба раза использовать ссылку(&$v)
пример:
$res=[1,2,3];
foreach($res as &$v){}
print_r($res);
foreach($res as &$v){}
print_r($res);
-------------------------------

Array
(
    [0] => 1
    [1] => 2
    [2] => 3
)
Array
(
    [0] => 1
    [1] => 2
    [2] => 3 //теперь все ожидаемо
)
 [2018-05-16 19:50 UTC] peehaa@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: peehaa
 [2018-05-16 19:50 UTC] peehaa@php.net
Duplicate of https://bugs.php.net/bug.php?id=76336 and many others
 [2018-05-17 14:01 UTC] spam2 at rhsoft dot net
this is NOT a bug - your code is buggy - it's that simple

<?php
 $array1 = [1, 2, 3];
 $array2 = [5, 6, 7];
 foreach($array1 as $key=>&$item)
 {
 }
 foreach($array2 as $key=>$item)
 {
  $item = "TEST $key";
 }
 print_r($array1);
 print_r($array2);
 $item = 'JESUS';
 print_r($array1);
?>
_______________________

<?php
 $array1 = [1, 2, 3];
 $array2 = [5, 6, 7];
 foreach($array1 as $key=>&$item)
 {
 }
 unset($item); /** THIS IS THE FIX */
 foreach($array2 as $key=>$item)
 {
  $item = "TEST $key";
 }
 print_r($array1);
 print_r($array2);
 $item = 'JESUS';
 print_r($array1);
?>
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Sat Jul 05 16:01:33 2025 UTC