php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #78387 references won't work for coalesce result
Submitted: 2019-08-08 21:17 UTC Modified: 2019-08-09 07:57 UTC
From: mpatnode at popsugar dot com Assigned:
Status: Not a bug Package: Scripting Engine problem
PHP Version: 7.4.0beta2 OS: any
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: mpatnode at popsugar dot com
New email:
PHP Version: OS:

 

 [2019-08-08 21:17 UTC] mpatnode at popsugar dot com
Description:
------------
Not sure if this is a bug, but the behavior is unexpected.  If a coalesce result is used in a foreach with a reference, the reference is ignored.   

If it's not legal syntax, then the reference should generate a warning or notice.

Behaved the same on every PHP version I tested.


Test script:
---------------
$foo = ['bar1' => 1, 'bar2' => 2];
foreach ($foo ?? [] as &$bar) { $bar = 3; }
var_dump($foo)

Expected result:
----------------
array(2) {
  'bar1' =>
  int(3)
  'bar2' =>
  int(3)
}

Actual result:
--------------
array(2) {
  'bar1' =>
  int(1)
  'bar2' =>
  int(2)
}

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2019-08-08 21:48 UTC] requinix@php.net
-Status: Open +Status: Not a bug -Package: Arrays related +Package: Scripting Engine problem
 [2019-08-08 21:48 UTC] requinix@php.net
This is documented, more or less, with the ?? operator itself.

https://www.php.net/manual/en/language.operators.comparison.php#language.operators.comparison.coalesce
> Note: Please note that the null coalescing operator is an expression, and that it doesn't evaluate to a variable,
> but to the result of an expression. This is important to know if you want to return a variable by reference. The
> statement return $foo ?? $bar; in a return-by-reference function will therefore not work and a warning is issued.

Since $foo ?? [] is an expression, $bar will not be a reference to a value inside $foo but to a value inside the *copy of* $foo that was "returned" by the expression. It's legal syntax, just not what you wanted it to do.
 [2019-08-08 22:22 UTC] mpatnode at popsugar dot com
You suggest a warning should of been issued for asking for a reference from an expression? We look for messages at the Notice level and didn't see anything in this case.
 [2019-08-08 22:30 UTC] requinix@php.net
As the note says,
> The statement return $foo ?? $bar; in a return-by-reference function will therefore not work and a warning is
> issued.
the warning is when returning from a return-by-reference function.
 [2019-08-09 07:57 UTC] nikic@php.net
The reason why this code doesn't generate a warning is that iterating a value by-reference can still be meaningful: Either because it has interior references, or because it's an iterator that produces references.

I believe this kind of code used to generate a compile-error prior to PHP 5.5, but the restriction was removed as part of generator support (which can yield by reference).
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Sat Sep 20 09:00:01 2025 UTC