12

对于声明如下的任意函数:

function foo($first, &$second = null) {
    // if ($second is assigned) {
    //     Work with $second
    // }
}

如何确定$second在调用时是否确实分配给变量,例如:

foo('hello', $second);

对比

foo('hello'); // Notice &$second is unassigned

试过了isset()is_null()但它们似乎不起作用。

更新:

在这里创建了一个测试脚本

4

4 回答 4

3

我的理解是,您希望实现一个实现类似 的函数,preg_match如果通过,第三个参数将填充内存模式。

在内部,PHP 函数使用一个名为zend_parse_parameters();的函数。它接受格式字符串和可变数量的参数,这些参数将填充调用参数的元数据。如果未传递参数(例如,当它是可选的),则元数据不可用,因此很容易检测到。

回到 PHP 本身,不幸的是没有这样的东西func_arg_used($var)可以告诉你是否$var作为函数参数传递;也许这对语言来说是一个有趣的贡献,但在那之前你必须满足于更古老的东西:)

if (func_num_args() > 1) {
    // $second was passed and can be used to populate
}

更改函数的签名时可能需要小心,尤其是在$second; 前面添加参数时。但是,这自然不应该经常发生,因为它肯定会破坏依赖函数。最后添加更多参数对上面的代码没有影响。

有两种方法可以使用:

  1. ReflectionFunction- 开发人员的闪亮新玩具,它允许您自省您的功能并确定签名是否从创建时更改。不过,谨慎使用它,内省并不便宜,尤其是考虑到替代方法。

  2. 不起眼的代码注释——代码监管的低调形式;一条简单的线说// IMPORTANT - don't add arguments before $second

于 2012-10-29T12:09:55.843 回答
1

我认为 Jack 使用func_num_args () 的建议非常好。

function foo($first, &$second = null) {
    if (func_num_args() > 1) {
        //$second MUST be assigned
    }
}

这可以正确检测何时$second引用了调用范围的符号表中存在的变量,但它的变量值为 null。

$second = null;
foo('hello', $second);
于 2012-10-28T18:30:31.067 回答
1

为我工作

<?php

function bool_str($b)
{
    return ($b ? "true" : "false");
}

function foo($first, &$second = null)
{
    echo bool_str(isset($first)) . " " . bool_str(isset($second)) . " " .
         bool_str(is_null($first)) . " " . bool_str(is_null($second)) . "\n";
}

$a = 1;
$b = 2;

foo($a, $b);
foo($a);

?>

输出:

true true false false
true false false true
     ^^^^^       ^^^^

这正是我所期望的,即你可以同时使用issetis_null这里。

于 2012-10-28T18:10:54.210 回答
1

你不能(据我所知)使用 isset 来区分 NULL 和 Undefined。您可以将 $second 的默认值设置为其他永远不会使用的随机值。

define('UNDEFINED', -19181818);

function foo($first, &$second = UNDEFINED) 
{
 if($second==UNDEFINED)
 {
  etc..
 }
}
于 2012-10-28T17:24:41.990 回答