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 this is not your bug, you can add a comment by following this link.
If this is your bug, but 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

Add a Patch

Pull Requests

Add a Pull Request

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-2024 The PHP Group
All rights reserved.
Last updated: Tue Apr 16 22:01:27 2024 UTC