php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #81306 PHP doesn't fully evaluate new expressions passed in named arguments
Submitted: 2021-07-28 20:35 UTC Modified: 2021-07-28 21:36 UTC
From: raincomplain at outlook dot com Assigned:
Status: Not a bug Package: Scripting Engine problem
PHP Version: 8.1.0beta1 OS:
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: raincomplain at outlook dot com
New email:
PHP Version: OS:

 

 [2021-07-28 20:35 UTC] raincomplain at outlook dot com
Description:
------------
According to the RFC of "New in initializers":

Parameter default values are evaluated from left to right on every call to the function where the parameter is not explicitly passed.

So calling a method by not explicitly passing a default paramater and using named arguments to call other arguments should trigger default parameter evaluation, so far so good. However, if both arguments are objects of the same class that modify a static property, PHP only returns the copy of the default object and "overlooks" the other object that was passed as a named argument.

Test script:
---------------
class A
{
    public static int $x = 0;

    public function __construct(int $x)
    {
        self::$x = $x; // changing this to self::$x += $x; works as expected
    }
}

function getTest(A $o1 = new A(88), A $o2 = new A(77))
{
    return A::$x;
}

var_dump(getTest(o2: new A(55)))

Expected result:
----------------
int(55)

Actual result:
--------------
int(88)

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2021-07-28 20:44 UTC] nikic@php.net
-Status: Open +Status: Not a bug
 [2021-07-28 20:44 UTC] nikic@php.net
This example is extremely weird. Let's make it more obvious by dropping the static property and just dumping in the constructor:

<?php

class A {
    public function __construct(int $x) {
        var_dump($x);
    }
}

function getTest(A $o1 = new A(88), A $o2 = new A(77)) {
}

getTest(o2: new A(55));

This prints int(55) followed by int(88), exactly as it should. First the new A(55) object is created explicitly and passed to parameter $o2, and then new A(88) is created when filling in the default value for parameter $o1.
 [2021-07-28 21:00 UTC] raincomplain at outlook dot com
We can't dropp the static property because then there will be no bug. 
Isn't: 
var_dump(getTest(new A(88),  new A(55))) 

equivalant to: 
var_dump(getTest(o2: new A(55)))

in my test script ?
 [2021-07-28 21:14 UTC] raincomplain at outlook dot com
If they are equivalant(as I believe)then this is a bug.
 [2021-07-28 21:27 UTC] nikic@php.net
They are only the same modulo evaluation order, and evaluation order is relevant in this example. The explicitly passed arguments are evaluated before any parameter default values.
 [2021-07-28 21:36 UTC] raincomplain at outlook dot com
Thanks Nikita, I was wrong when I thought parameter default values are evalutaed first.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Mon Apr 29 00:01:32 2024 UTC