特别";“未定义”;PHP函数中参数的默认值的值

特别";“未定义”;PHP函数中参数的默认值的值,php,function,default-parameters,default-arguments,Php,Function,Default Parameters,Default Arguments,我需要一个可选参数,该参数接受任何值(包括null和false),但仍具有“未指定”状态,以允许不同的“默认”行为。PHP中有没有允许模仿“未定义”值的技术 我想将append方法添加到.NET的LINQ端口YaLinqo中。当前代码如下所示: public function append ($value, $key = null) { return new self(function () use ($value, $key) { foreach ($this as

我需要一个可选参数,该参数接受任何值(包括
null
false
),但仍具有“未指定”状态,以允许不同的“默认”行为。PHP中有没有允许模仿“未定义”值的技术


我想将
append
方法添加到.NET的LINQ端口YaLinqo中。当前代码如下所示:

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;
    });
}
问题是,如果有人想使用
null
作为键,他们将无法这样做,因为它当前是一个特殊的“未定义”值,这将导致使用自动顺序整数。在PHP中,包含序列
[null=>null,null=>null]
的迭代器是完全有效的,用户应该能够使用
append
生成它

我正在考虑添加
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;
    });
}

这是一种有效的方法吗?有更干净的方法吗?

没有简单的方法可以做到这一点。在您的情况下,用户仍然可以使用
{YaLinqo.Utils.Undefined}
值定义$key,在这种情况下,将执行不正确的代码分支。我只能想到一个解决方案——我们可以分析调用堆栈帧,以确定用户是否传递了一些参数。像这样:

<?php

function test() {
 func(1, null);
 func(1); 
}

function func ($x, $y = null) { 
  $stack = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT, 1);
  if (count($stack[0]['args']) == 2)
    echo "\$y argument is defined\n";
  else
    echo "\$y argument is UNDEFINED\n";
}

test();

?>

您可以使用
func\u get\u args()
实现您想要的功能。请看以下示例:

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

test(1);
test(2, null);
以下是输出:

array(1) {
  [0]=>
  int(1)
}
array(2) {
  [0]=>
  int(2)
  [1]=>
  NULL
}
正如您所看到的,参数列表只包含传入的参数,而不包含定义的参数。如果您想知道某人是否显式传递了
null
,您可以执行以下操作:

$args = func_get_args();
if (isset($args[1]) && $args[1] === null) {}
$args = func_get_args();
if (!isset($args[1])) {}
或者,如果您想知道参数未通过,可以执行以下操作:

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