php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #76412 Nullable type default value
Submitted: 2018-06-05 08:55 UTC Modified: 2018-06-05 09:17 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: ionuthrive at yahoo dot com Assigned:
Status: Not a bug Package: Scripting Engine problem
PHP Version: 7.2.6 OS: All
Private report: No CVE-ID: None
 [2018-06-05 08:55 UTC] ionuthrive at yahoo dot com
Description:
------------
When passing null to a optional nullable type argument, the default value is overwritten.

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

function get(string $id, ?int $limit = 1, ?string $type = 'standard', ?array $options = []){
    var_dump($limit);
    var_dump($type);
}

get(1, null, 'custom');
get(1, 10, null, ['my'=>'option']);

Expected result:
----------------
Since 7.1 when the nullable types could be marked as null the situation where one needs to call a function while skipping some parameters is met with overwrite of the default values of the function arguments.

For the above test script, when passing null and the argument is specifically declared as a nullable type, the parser should know to take the default value instead of overriding it as NULL.

feature-php.php:4:
1
feature-php.php:5:
string(6) "custom"
feature-php.php:4:
int(10)
feature-php.php:5:
standard

Actual result:
--------------
feature-php.php:4:
NULL
feature-php.php:5:
string(6) "custom"
feature-php.php:4:
int(10)
feature-php.php:5:
NULL

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2018-06-05 09:11 UTC] daverandom@php.net
-Status: Open +Status: Not a bug
 [2018-06-05 09:11 UTC] daverandom@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php

This is by design. Passing null does not always indicate "skip this parameter and use the default", null may also have a semantic meaning.

The behaviour you want can be easily achieved in combination with the ?? operator, something like:

function get(string $id, ?int $limit = 1, ?string $type = 'standard', ?array $options = []){
    var_dump($limit ?? 1);
    var_dump($type ?? 'standard');
    var_dump($options ?? []);
}

In combination with private class constants, you can also avoid specifying the default value more than once in code, retaining correct information reported by reflection/IDEs etc:

class Foo
{
    private const DEFAULT_LIMIT = 1;
    private const DEFAULT_TYPE = 'standard';
    private const DEFAULT_OPTS = [];

    public function get(string $id, ?int $limit = self::DEFAULT_LIMIT, ?string $type = self::DEFAULT_TYPE, ?array $options = self::DEFAULT_OPTS)
    {
        var_dump($limit ?? self::DEFAULT_LIMIT);
        var_dump($type ?? self::DEFAULT_TYPE);
        var_dump($options ?? self::DEFAULT_OPTS);
    }
}
 [2018-06-05 09:17 UTC] requinix@php.net
-Type: Feature/Change Request +Type: Bug -Package: PHP Language Specification +Package: Scripting Engine problem
 [2018-06-05 09:17 UTC] requinix@php.net
Having the engine assume that null implies the default means you couldn't pass an actual null value.

An idea to use "default" as a keyword was declined. https://wiki.php.net/rfc/skipparams
Named parameters were another approach. https://wiki.php.net/rfc/named_params

If you have a new idea that you want to propose then check out the RFC process. https://wiki.php.net/rfc/howto
Otherwise this should be addressed in code like how @daverandom showed.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Apr 19 16:01:27 2024 UTC