php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #80296 Migration docs regarding foreach needs examples and clarification
Submitted: 2020-10-29 17:42 UTC Modified: 2020-10-30 13:33 UTC
From: php4fan at gmail dot com Assigned:
Status: Verified Package: Documentation problem
PHP Version: Irrelevant OS: all
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2020-10-29 17:42 UTC] php4fan at gmail dot com
Description:
------------
---
From manual page: https://www.php.net/manual/en/migration70.incompatible.php#migration70.incompatible.foreach.by-value
---

It says:

"""
foreach by-value operates on a copy of the array ΒΆ
When used in the default by-value mode, foreach will now operate on a copy of the array being iterated rather than the array itself. This means that changes to the array made during iteration will not affect the values that are iterated.
"""

It is unclear what this means, because what I understand from it is not true. 

Also, an example should be given, with different output for 5.x vs 7.x.
Even if the explanation wasn't ambiguous as it is, an example should ALWAYS be given for all documented changes. 

Test script:
---------------
Consider these scripts:

<?php // EXAMPLE 1

  $a = ['x', 'y', 'z'];
  
  foreach ($a as $i => $v) {
      $a[$i] = '!!!';
  }
  
  print_r($a);
?>


<?php // EXAMPLE 2

  $a = ['x', 'y', 'z'];
  
  foreach ($a as $v) {
      $a[1] = '!!!';
  }
  
  print_r($a);
?>





Expected result:
----------------
In PHP 5, the first example outputs:

Array
(
    [0] => !!!
    [1] => !!!
    [2] => !!!
)

and example 2 outputs:

Array
(
    [0] => x
    [1] => !!!
    [2] => z
)

as expected.

From the confusing statement cited above, I would seem to understand (and that would surprise me) that the first example in PHP 7 would output:

Array
(
    [0] => x
    [1] => y
    [2] => z
)

or perhaps, that example 1 would work as in PHP 5, but that example 2 would output

Array
(
    [0] => x
    [1] => y
    [2] => z
)

Actual result:
--------------
Fortunately, that is not the case. But then, I'm completely lost as to what the sentence means.

I can't figure out an example where the behavior in PHP 5 and 7 would differ.

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2020-10-29 18:04 UTC] cmb@php.net
-Status: Open +Status: Verified
 [2020-10-29 18:04 UTC] cmb@php.net
UPGRADING has a nice example[1], but that is neither in the
migration guide nor in the manual proper.

[1] <https://3v4l.org/DIEqs>
 [2020-10-29 22:26 UTC] a at b dot c dot de
Perhaps it should be clarified that "changes to the array" refers to changing the array itself (its structure) rather than to changing the values stored in the array.

The version 7 change means that adding or removing array elements within a foreach loop doesn't affect which elements are looped over (so a removed element will still be iterated over, and an added element won't be).
 [2020-10-30 13:33 UTC] cmb@php.net
From what I can tell, it's really just about the array separation
(i.e. only relevant if a reference to the array exists).  Removal
from a non-referenced array seems to be ignored in PHP 5 as well:
<https://3v4l.org/avS1F>.
 
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Sat Dec 05 06:01:23 2020 UTC