php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #70857 Foreach with a reference is modifying the result of a ternary expression
Submitted: 2015-11-04 20:45 UTC Modified: 2017-01-31 10:51 UTC
From: nairebis at gmail dot com Assigned: nikic (profile)
Status: Closed Package: Variables related
PHP Version: 5.6.15 OS: CentOS 6.7
Private report: No CVE-ID: None
 [2015-11-04 20:45 UTC] nairebis at gmail dot com
Description:
------------
Consider this line, where $a is an array:

    foreach (1 ? $a : [] as &$x) {

According to the PHP documentation on ternary expressions, "Note: Please note that the ternary 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 $var == 42 ? $a : $b; in a return-by-reference function will therefore not work and a warning is issued in later PHP versions."

The result of the ternary expression should not be an lvalue, and thus the above shouldn't work. But it actually does allow this.

Test script:
---------------
    $a = [1, 2, 3, 4];
    foreach (1 ? $a : [] as &$x) {
        $x += 10;
    }
    print_r($a);


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


Actual result:
--------------
Array
(
    [0] => 11
    [1] => 12
    [2] => 13
    [3] => 14
)

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-11-05 01:37 UTC] bwoebi@php.net
This is fixed in PHP 7.

Also it has inconsistent behavior thanks to copy on write: https://3v4l.org/jMjc8#v550
 [2017-01-31 10:51 UTC] nikic@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: nikic
 [2017-01-31 10:51 UTC] nikic@php.net
Closing as this is fixed in PHP 7 and PHP 5.6 is out of active support.
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Sun Dec 15 20:01:28 2019 UTC