php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #81147 getDefaultValue() throws if a mandatory parameter follows
Submitted: 2021-06-16 18:02 UTC Modified: 2021-06-16 18:37 UTC
From: me at derrabus dot de Assigned:
Status: Closed Package: Documentation problem
PHP Version: 8.1.0alpha1 OS: macOS 11.4, Ubuntu 20.04
Private report: No CVE-ID: None
View Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
If you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: me at derrabus dot de
New email:
PHP Version: OS:

 

 [2021-06-16 18:02 UTC] me at derrabus dot de
Description:
------------
If I reflect on a function that has an optional parameter before a mandatory one and I try to fetch the default value of the optional parameter, a ReflectionException is raised. This was not the case on PHP 8.0 and earlier.

I am unsure if this is an intentional change because specifying a function where a mandatory parameter follows an optional one had already been deprecated in PHP 8.0. But I somewhat expected that the deprecation would not be turned into an error before PHP 9.

Test script:
---------------
<?php

function myFunctionA(object $arg1 = null)
{
}


function myFunctionB(object $arg1 = null, $arg2)
{
}

var_dump((new ReflectionParameter('myFunctionA', 0))->getDefaultValue());
var_dump((new ReflectionParameter('myFunctionB', 0))->getDefaultValue());

Expected result:
----------------
NULL
NULL

Actual result:
--------------
NULL

Fatal error: Uncaught ReflectionException: Internal error: Failed to retrieve the default value

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2021-06-16 18:18 UTC] krakjoe@php.net
-Package: Reflection related +Package: Documentation problem
 [2021-06-16 18:18 UTC] krakjoe@php.net
Because the parameter is implicitly nullable, no deprecation warning in shown in this case.

However the behaviour does not change, and the deprecation warning reads:

> Optional parameter $arg1 declared before required parameter $arg2 is implicitly treated as a required parameter

In other words, the default value is ignored, and the engine generates ZEND_RECV not RECV_INIT, leading to internal error in Reflection.

There's nothing to fix here, but this should be documented.
 [2021-06-16 18:33 UTC] me at derrabus dot de
Thank you for your very quick response, Joe!

> In other words, the default value is ignored

Yes, that is apparently what happens on PHP 8.1. However, I'd like to point out that it's not ignored on PHP 8.0. And this is why I've opened this bug: I'd like to clarify whether this change of behavior in 8.1 is a unintentional regression or an intentional BC break.
 [2021-06-16 18:33 UTC] nikic@php.net
Just to confirm, this is indeed an intentional change to ensure that optional-before-required is consistently treated as a required parameter. Previously it was treated as such in nearly all situations, but there were loopholes. One, as you have discovered, is reflection. The other is named arguments, where it was possible to not specify such a parameter if later required parameters were specified.
 [2021-06-16 18:37 UTC] me at derrabus dot de
-Status: Open +Status: Closed
 [2021-06-16 18:37 UTC] me at derrabus dot de
Thank you very much. <3 We can close the bug report then!
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Nov 01 01:01:28 2024 UTC