【问题标题】:How do I pass undefined vars to functions without E_NOTICE errors?如何将未定义的变量传递给没有 E_NOTICE 错误的函数?
【发布时间】:2012-04-12 19:50:26
【问题描述】:

真的很简单的问题,如何将未定义的变量传递给函数而不会出现 E_NOTICE 错误?

将未定义的变量传递给 isset() 等函数时,不会引发错误,但将其发送给您自己的函数,您会得到一个通知:未定义的偏移量:等。

我已经想到了今天想要这个的几个原因,但我当前的函数几乎是 isset 的克隆,除了它会检查是否设置了 any 的 args,而不是全部喜欢 isset( a,b,c) 会。

function anyset()
{
    $argc = func_num_args();
    $argv = func_get_args();
    for ($i = 0; $i < $argc; $i++) 
        if (isset($argv[$i])) return true;
    else return false;
}

现在,例如,我有一个巨大的 [x][y] 二维数组,其中的值将被随机放置。我需要检查随机坐标是否包含“旁边”的任何内容(x-1,y-1 到 x+1,y+1)等。

我不想循环 20,000,000 并初始化每个变量。我只想发送 9 个变量并检查是否已设置任何变量。

while (anyset($items[$x-1][$y-1],$items[$x][$y-1],$items[$x+1][$y-1],
              $items[$x-1][$y],$items[$x][$y],$items[$x+1][$y],
              $items[$x-1][$y+1],$items[$x][$y+1],$items[$x+1][$y+1]));

像这样。

我可以做 isset(x) || isset(x) || isset(x) 但这看起来不太好。

有没有办法让未定义的变量传递给我的函数而不会引发错误?

对采取简单的选择不感兴趣;)

感谢阅读!

\o

更新: 2012 年 4 月 12 日 21:03 看起来没有允许这种情况发生的特殊功能。因此,要么像 anyset(@$array[0], @$array[1]) 等一样通过,要么像这样将所有内容包装在一千个 issets 中:

while (isset($items[$x-1][$y-1]) || isset($items[$x][$y-1]) || isset($items[$x+1][$y-1]) || 
       isset($items[$x-1][$y])   || isset($items[$x][$y])   || isset($items[$x+1][$y]) || 
       isset($items[$x-1][$y+1]) || isset($items[$x][$y+1]) || isset($items[$x+1][$y+1]));

希望这对将来的其他人有所帮助!

【问题讨论】:

  • 简单的想法,只是在错误引发函数之前添加错误中和器@? $result = @youFunction()

标签: php


【解决方案1】:

您有三个选择:

  • 使用 isset 正确处理逻辑 (isset($x) || isset($y) || isset($z))
  • 将所有内容包装在 isset() 中,然后让您的函数检查是否有任何论点为真(有点 bleh)
  • 使用 @ 来抑制错误(也叫 bleh)

@ 的一个例子是:

function a($a) { } a(@$x);

您应该记住,通知的存在是有原因的。我避免错误抑制。这对我来说似乎很hacky。我会正确地将所有内容包装在 isset() 中。它更冗长,但无论如何,在我看来,更正确。

【讨论】:

  • 我明白了,我想到了这一点,但我也认为这有点 hacky。认为可能有一些神奇的方式允许未定义的变量作为 null/unset 传递。没问题,我想我会使用 9 个 issets!谢谢。
  • @AdamKDean 好吧,总是有调整错误报告级别的选项。我会提到这是一个选项,除了它不是特定于这部分代码的。它将特定于整个代码运行。例如 error_reporting(E_ALL ^ E_NOTICE);会忽略通知。但问题是,它会忽略 all 通知,而不仅仅是使用未定义的变量。您可以仅将函数调用包装在 error_reporting() 中,然后将错误报告恢复为正常状态,但这对我来说似乎更骇人听闻。
  • @AdamKDean 另一种选择是在整个函数前面加上@。我认为您必须单独为每个变量添加前缀,但只是在 cmets 中测试了 Claaker 的建议,显然您可以为整个函数添加前缀以抑制通知。不过,这可能会出现一些您不希望出现的错误。
  • 我同意,理想情况下会有一种通过空变量发送的方法,可能类似于函数 anyset($argc, nullable params $argv),尽管这刚刚开始看起来像 C#。跨度>
  • 嗯,我喜欢这种行为。事实上,如果我做出决定,我可能会把它变成一个错误,而不是一个通知。尽管在这种情况下您不得不进行大量冗长的 isset() 调用,但我可以看到它可能令人讨厌的地方。
【解决方案2】:

通过引用传递将适用于已定义的参数。

function my_isset(&$k) { ... }

$bool = my_isset($_POST['hi']);

【讨论】:

  • 如果 $_POST 的 'hi' 键不存在,它仍然会抛出一个通知。
  • 如果通过引用(&)传递,则不会抛出通知。这不适用于 func_get_args。您可以尝试使用 debug_backtrace,但仍然会触发通知
  • 我认为这是正确的答案 - 通过引用传递将停止生成警告。
  • 在 php 7.3 通过引用传递停止了警告消息。因此,这似乎是正确的答案 (+1)。
【解决方案3】:

isset 有点特别,因为它实际上是一个 PHP 语言结构,而不是一个函数 [1]

如果一个变量是未定义的,你不能真正传递它,因为它没有定义(因此警告)。

如 cmets 中所述,您可以通过在变量前添加 @ 来抑制警告,如果未设置,则不会发出警告。然后在函数中,您可以检查该值是否为空或尝试使用isset 来查看它是否已注册。

【讨论】:

  • 有趣,没有意识到这一点,尽管我确实认为它可能是一个特殊的内置功能。笨蛋。无论如何,谢谢,猜测 issets 必须是要走的路!
【解决方案4】:

也许这样的东西对你有用?这有点骇人听闻,但我认为如果不对函数参数进行惰性求值,您想要的就不太可能。

if (atLeastOneIsSet($myArray, 1, 3, 4, 6)) doSomething();

function atLeastOneIsSet(array $arr) {
    $args = func_get_args();
    for ($i = 1; $i < func_num_args(); ++$i)
        if (isset($arr[$args[$i]])) return true;
    return false;
}

编辑:哎呀,逻辑问题。

【讨论】:

  • 将其设置为与 2d 数组一起使用会比仅使用 issets 更糟糕。你能想象 atLeastOneIsSet($array, array(0,0), array(1,0), array(1,1)) 等吗?不过谢谢,有趣的概念!
  • @AdamKDean 哎呀,我想我太着急发帖了。这些该死的 PHP 问题总是让我觉得很匆忙!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-11
  • 1970-01-01
  • 2020-12-04
  • 1970-01-01
相关资源
最近更新 更多