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
View Add Comment Developer Edit
Anyone can comment on a bug. Have a simpler test case? Does it work for you on a different platform? Let us know!
Just going to say 'Me too!'? Don't clutter the database with that please — but make sure to vote on the bug!
Your email address:
MUST BE VALID
Solve the problem:
33 - 16 = ?
Subscribe to this entry?

 
 [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-2021 The PHP Group
All rights reserved.
Last updated: Mon Apr 19 07:01:24 2021 UTC