PHP - 如何使参考参数变为可选?

48

假设我在PHP中定义了一个函数,并且最后一个参数是通过引用传递的。有没有办法使它变成可选的?我如何知道它是否被设置了值?

我从未在PHP中使用过按引用传递,因此下面可能会有一些愚蠢的错误,但这里是一个示例:

$foo;
function bar($var1,&$reference)
{
    if(isset($reference)) do_stuff();
    else return FALSE;
}

bar("variable");//reference is not set
bar("variable",$foo);//reference is set
8个回答

68

摘自PHP官方手册

NULL可以用作默认值,但无法从外部传递

<?php

function foo(&$a = NULL) {
    if ($a === NULL) {
        echo "NULL\n";
    } else {
        echo "$a\n";
    }
}

foo(); // "NULL"

foo($uninitialized_var); // "NULL"

$var = "hello world";
foo($var); // "hello world"

foo(5); // Produces an error

foo(NULL); // Produces an error

?>

1
看看@Michal Lohniský的评论(https://dev59.com/YGQn5IYBdhLWcg3wr446#29895514)。他对于NULL有很好的见解。 - samuelg0rd0n
3
我知道这是一个古老的问题,但对于将来会看到这个答案的人来说,foo(5)和foo(NULL)会抛出错误,因为只有变量可以通过引用传递(5和NULL不是变量)。 - Răducanu Ionuţ
1
需要注意的一点是,调用者可能会使用一个值为“null”的变量调用函数。因此,如果引用变量纯粹被用作输出变量,则没有必要检查它是否为null - 如果在调用函数之前变量包含null,这样做可能会导致意外的行为。 - Magnus

12

10

您可以通过给参数设置默认值来使它们变为可选:

function bar($var1, &$reference = null)
{
    if($reference !== null) do_stuff();
    else return FALSE;
}

然而请注意,通常情况下,按引用传递是不良实践。如果突然更改了$foo的值,则必须查找原因,只有发现它是通过引用传递才能找到。因此,请仅在有有效用例时使用它(并且相信我,大多数用例都没有)。

还要注意,如果$reference应该是一个对象,则可能不需要(也不应该)按引用传递,可以查看此链接获取更多信息。

另外,当前您的函数正在返回不同类型的值。当传递引用时,它返回null,否则返回false


如果不是因为“[...]默认情况下通过引用传递对象”,可能需要进一步澄清,我会点赞的。http://blog.golemon.com/2007/01/youre-being-lied-to.html - PleaseStand
1
@PleaseStand 我在谈论它在用户空间的行为。我可以开始谈论引用计数等,但我认为那只会让OP感到困惑。 - PeeHaa
如果你真的想了解它是如何工作的,我建议你观看这个视频:http://blog.ircmaxell.com/2012/12/programming-with-anthony-references.html。 - PeeHaa
1
请注意,一般情况下,通过引用传递参数是不好的做法。你认为使用 preg_match() 也是不好的做法吗? - hek2mgl
不要误解我的意思!我绝对不是什么“反对者”!我只是想指出,按引用传递并不是一种不好的做法。这是错误的。正确的做法是,按引用传递可能会产生副作用,这是一个经验不足的程序员可能没有预料到的。但当然也有按引用传递的原因。 - hek2mgl
显示剩余4条评论

3
你可以设置默认值。
$foo;
function bar($var1,&$reference = false)
{
    if($reference != false) do_stuff();
     else return FALSE;
}

bar("variable");//reference is not set
bar("variable",$foo);//reference is set

2

通过引用传递对于赋值非常有用,有时您不需要检查值是否为null。这将允许对变量进行无差别的赋值,包括未初始化的变量。

function f(&$ref = null) {
    $ref = 1234;
}

f($x);
echo $x; // 1234
f(); // No error

在像这样的代码中很有用:

if (doSomething($value, $errorMessage) === false) {
    logError($errorMessage);
}

doSomething($value); // Explicitly ignore error message

1
尝试
use function bar($var1,&$reference=null)
{
    if(isset($reference)) do_stuff();
    else return FALSE;
}

如果您将值传递给 &$reference,它将使用该值。否则为 null。

1
两种选择:
声明一个默认值,该值在常规值范围之外,例如-1
function bar($var1,&$reference = -1)
{
    if($reference !== -1) do_stuff();
    else return FALSE;
}

不要声明参数并检查func_get_args()以查看是否传递了它:
function bar($var1)
{
    if(count(func_get_args()) > 1) do_stuff();
    else return FALSE;
}

但是请注意,第二种方法会触发一个已弃用的警告:Call-time pass-by-reference has been deprecated;

如果(func_num_args() > 1)则执行操作(); - JJS

1
下面的代码片段说明了引用只是变量名称的别名:
<?php
function set_variable(&$var, $val)
{
  $var = $val;
}

set_variable($b, 2);
echo $b; // 2
?>

这篇由Larry Ullman撰写的文章解释了通过引用传递变量与通过值传递变量的基础知识。

有趣的是,在Larry的文章结尾处有一个链接,指向另一篇文章,深入解释了PHP中引用和变量的基础知识。

总的来说,当我们将引用参数设置为可选时,并给它一个默认值时,PHP会“创建”一个新变量,以便在我们没有为可选参数提供值时,使用默认值。但是,如果我们提供了值,我们必须提供一个变量,引用参数只是该变量的别名。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接