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
 [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

Add a Patch

Pull Requests

Add a Pull Request

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-2021 The PHP Group
All rights reserved.
Last updated: Sun Sep 19 12:03:36 2021 UTC