Search code examples
phpfunctiondefault-parametersdefault-arguments

Special "undefined" value for default value of argument in PHP function


I need an optional argument that accepts any value (including null and false), but still has "unspecified" state to allow a different "default" behavior. Is there any technique in PHP which allows imitating "undefined" value?


I want to add append method to YaLinqo, my port of .NET's LINQ. Currently the code looks like this:

public function append ($value, $key = null)
{
    return new self(function () use ($value, $key) {
        foreach ($this as $k => $v)
            yield $k => $v;
        if ($key !== null)
            yield $key => $value;
        else
            yield $value;
    });
}

The problem is, if somebody wants to use null as a key, they won't be able to do it, as it's a special "undefined" value currently, which will cause yielding using automatic sequental integer. In PHP, iterator containing sequence [ null => null, null => null ] is perfectly valid and user should be able to produce it using append.

I'm considering adding const UNDEFINED = '{YaLinqo.Utils.Undefined}':

const UNDEFINED = '{YaLinqo.Utils.Undefined}';

public function append ($value, $key = Utils::UNDEFINED)
{
    return new self(function () use ($value, $key) {
        foreach ($this as $k => $v)
            yield $k => $v;
        if ($key !== Utils::UNDEFINED)
            yield $key => $value;
        else
            yield $value;
    });
}

Is this a valid approach? Is there a cleaner way?


Solution

  • You could use func_get_args() to achieve what you want. Take a look at the following example:

    function test($value, $key = null) {
        var_dump(func_get_args());
    }
    
    test(1);
    test(2, null);
    

    And here is the output:

    array(1) {
      [0]=>
      int(1)
    }
    array(2) {
      [0]=>
      int(2)
      [1]=>
      NULL
    }
    

    As you can see the argument list only contains passed in arguments and not defined arguments. If you want to know if someone explicitly passed null you can do:

    $args = func_get_args();
    if (isset($args[1]) && $args[1] === null) {}
    

    Or if you want to know the argument was not passed you can do:

    $args = func_get_args();
    if (!isset($args[1])) {}