Php 函数参数错误抑制,empty() isset() 仿真

Php function argument error suppression, empty() isset() emulation

提问人:SeanDowney 提问时间:9/11/2008 最后编辑:Alive to die - AnantSeanDowney 更新时间:7/10/2019 访问量:5332

问:

我很确定这个问题的答案是否定的,但万一有一些PHP大师

是否可以以可以传入无效参数或不存在的变量的方式编写函数,并且 php 在不使用'@'

就像空的和是空的一样。你可以传入一个你刚刚编造的变量,它不会出错。

ex:

empty($someBogusVar); // no error

myHappyFunction($someBogusVar); // Php warning / notice
PHP 处理 错误 抑制

评论

2赞 reefnet_alex 9/11/2008
不知道为什么这被否决了,对我来说似乎是一个合理的问题
0赞 Brian Warshaw 9/11/2008
他只是完全改变了这个问题。他需要关闭它并询问一个新的是否是他想做的。他也撕掉了他的整个例子。
0赞 SeanDowney 9/11/2008
我不确定 stackover flow 上的正确协议是什么,但如果这是我应该做的,我会这样做
0赞 reefnet_alex 9/11/2008
问题的实质是:可以以一种可以传递无效参数或不存在变量的方式编写函数,并且 php 在不使用相同的“@”的情况下不会出错。我按照措辞回答了这个问题,我的回答将适用于旧措辞或新措辞

答:

1赞 Adam Wright 9/11/2008 #1

不,因为这与函数没有任何关系;该错误来自尝试取消引用不存在的数组键。您可以更改 PHP 设置的警告级别来抑制这些错误,但最好不要这样做。

话虽如此,你可以做这样的事情

function safeLookup($array, $key)
{
  if (isset($array, $key))
    return $array[$key];

  return 0;
}

并用它来代替数组键查找

defaultValue(safeLookup($foo, "bar"), "baz);

现在我需要洗个澡:)

0赞 SeanDowney 9/11/2008 #2

@Brian:我使用三位一体运算为我进行检查:

return $value ? $value : $default;

这将返回 $value 或 $default。取决于$value的值。如果它是 0、false、empty 或类似的东西,则将返回 $default 中的值。

我更愿意挑战模拟 empty() 和 isset() 等函数

-1赞 Vinko Vrsalovic 9/11/2008 #3

再往上看抽象树,你用它来做什么?

您可以根据需要初始化每个类中的这些值,也可以创建包含所有默认值和属性的特定类,例如:

class Configuration {

    private var $configValues = array( 'cool' => 'Defaultcoolval' ,
                                       'uncool' => 'Defuncoolval'  );

    public setCool($val) {
        $this->configValues['cool'] = $val;
    }

    public getCool() {
        return $this->configValues['cool'];
    }

}

这个想法是,当在代码中的所有位置上下使用 defaultValue 函数时,每当您必须更改值时,它都会成为维护的噩梦,寻找放置 defaultValue 调用的所有位置。这也可能导致你重复自己,违反 DRY。

而这是存储所有这些默认值的单一位置。您可能很想避免创建这些 setter 和 getter,但它们也有助于维护,以防对输出进行一些修改或验证输入变得相关。

0赞 SeanDowney 9/11/2008 #4

我敢肯定,关于三元运算符 vrs 函数调用可能会有很好的讨论。但这个问题的重点是看看我们是否可以创建一个函数,如果在不使用“@”的情况下传入一个不存在的值,它不会引发错误

4赞 reefnet_alex 9/11/2008 #5

您可以使用如下func_get_args来执行此操作:

error_reporting(E_ALL);
ini_set('display_errors', 1);

function defaultValue() {
    $args = func_get_args();

    foreach($args as $arg) {
        if (!is_array($arg)) {
            $arg = array($arg);
        }
        foreach($arg as $a) {
            if(!empty($a)) {
                return $a;
            }
        }
    }

    return false;
}

$var = 'bob';

echo defaultValue(compact('var'), 'alpha') . "\n"; //returns 'bob'
echo defaultValue(compact('var2'), 'alpha') . "\n"; //returns 'alpha'
echo defaultValue('alpha') . "\n"; //return
echo defaultValue() . "\n";

这个函数更进一步,会给你任意数量的参数的第一个非空值(你总是可以强制它只接受最多两个参数,但这看起来对我更有用,就像这样)。

编辑:原始版本没有使用压缩来尝试制作参数数组,并且仍然给出错误。错误报告提升了一个档次,这个带有 compact 的新版本有点不那么整洁,但仍然做同样的事情,并允许您为不存在的变量提供默认值。

评论

0赞 SeanDowney 9/11/2008
我仍然收到一个未定义的错误:注意:未定义的变量:第 19 行文件.php中的 var2
0赞 reefnet_alex 9/11/2008
窃听 - 你是对的:)好的,这个版本修复了它。您必须使用 compact 从混合中提取变量(包括任何不存在的幻想变量),但仍然应该允许一些紧凑代码(没有双关语的意思)
0赞 SeanDowney 9/11/2008
这是对紧凑函数的巧妙使用。我从未见过这样的用途,感谢您的提示。
0赞 Vinko Vrsalovic 9/11/2008 #6

@Sean 布莱恩已经回答了这个问题

return isset($input) ? $input : $default;

评论

0赞 SeanDowney 9/11/2008
但是在函数中,错误已经触发了是吗?
0赞 Brian Warshaw 9/11/2008 #7

肖恩,你可以做:

$result = ($func_result = doLargeIntenseFunction()) ? $func_result : 'no result';

编辑:

我敢肯定可能会有一个伟大的 关于三元算子VRS的讨论 函数调用。但重点是 问题是看看我们是否可以创建一个 如果出现以下情况,则不会引发错误的函数 传入一个不存在的值 不使用“@”

我告诉过你,用.三元条件的第一部分不检查 null 或 not null,而是检查 或 .如果您尝试在 PHP 中检查 或 空值,则会收到这些警告。 检查变量或表达式是否返回 null 值,并返回一个布尔值,该布尔值可以由三元的第一部分计算,而不会出现任何错误。isset()truefalsetruefalseisset()

8赞 Vinko Vrsalovic 9/11/2008 #8

总而言之,正确的答案是否定的,你不应该(见下面的警告)。

在这个线程中,许多人已经提到了一些解决方法,例如在条件中使用引用变量或 isset() 或 empty() 以及在 PHP 配置中抑制通知。除了明显的解决方法之外,使用您不想要的 @。

总结与 Gerry 的一个有趣的评论讨论:如果您检查函数内部变量的值并正确处理未定义或 null 情况,则通过引用传递变量确实有效。只是不要使用引用传递作为关闭PHP的一种方式(这是我的原始不应该指向的地方)。

评论

0赞 Gerry 6/5/2009
你的粗体陈述不正确,请看porneL的回答: stackoverflow.com/questions/55060/884770#answer-311954
0赞 dirtside 6/5/2009
他用粗体字写的陈述并无不妥。如果您设计的函数需要抑制由缺少参数引起的警告/错误,那么您的函数设计错误,需要重新开始。porneL 的答案是一个有效的解决方法,但这不是一个好主意。
0赞 Vinko Vrsalovic 6/5/2009
我只是编辑了我的答案以纠正不正确的粗体陈述,我不知道引用技巧。
0赞 Gerry 6/7/2009
它说“不,你不能”。文科似乎同意该声明不正确并对其进行了修改,我对此表示感谢。它也不会抑制错误。在将未定义的变量用作参数的情况下,它正在创建一个空引用,然后可以在 myHappyFunction() 中测试该引用以查看它是否真的存在。我仍然不同意这是如何重写的。您绝对不应该使用这种技术来抑制错误,但它确实具有有效的应用程序,例如创建问题中要求的替代 empty() 函数!
0赞 Vinko Vrsalovic 6/7/2009
该问题没有要求创建一个替代的 empty() 函数,只是要求创建一个与未定义变量具有类似 empty() 行为的函数,这些变量没有指定用法。我仍然坚持认为你不应该。我认为没有必要通过所有可能的例外来限定大多数不应该的例外,这些例外总是存在的。如果你知道自己在做什么,你当然可以做你不应该做的事情,而不会产生任何有害的副作用。
12赞 Kornel 11/23/2008 #9

当一个变量被引用传递时,你不会得到任何错误(PHP将静默地创建一个新变量):

 function myHappyFunction(&$var)
 {       
 }

但我建议不要滥用它来隐藏编程错误。

评论

0赞 Samuel Åslund 9/4/2017
在许多情况下,这是正确的做法,例如以标准方式处理(可能)丢失的传入 POST 变量。感谢您对问题的实际答案!
0赞 supersan 3/7/2019
@SeanDowney 这应该是最高和公认的答案。它准确地回答了你所问的问题。被接受的答案(说“不”)是不正确的,因为 SO 应该有答案而不是意见(即不,你不应该这样做)。
0赞 Arthur McLean 2/3/2009 #10

虽然原始问题的答案是否定的,但有一个选项没有人提到。

当你使用 @ 符号时,PHP 所做的只是覆盖级别并暂时将其设置为零。您可以使用 “” 将其设置回使用 @ 之前的任何状态。error_reportingini_restore('error_reporting');

在我想编写一个方便的函数来检查和查看是否设置了变量并且还具有其他一些属性的情况下,这对我很有用,否则,返回默认值。但是,发送一个未设置的变量会导致 PHP 通知,所以我使用 @ 来抑制它,但随后又设置回函数内的原始值。error_reporting

像这样:

$var = @foo($bar);

function foo($test_var)
{
     ini_restore('error_reporting');

     if(is_set($test_var) && strlen($test_var))
     {
          return $test_var;
     }
     else
     {
          return -1;
     }
}

因此,在上面的情况下,如果未设置,则在使用不存在的变量进行调用时不会出现错误。但是,我会从函数中收到一个错误,我错误地输入了 .$barfoo()is_setisset

这可能是一个有用的选择,涵盖了原始问题在精神上提出的问题,如果不是实际情况的话。

1赞 Gerry 5/20/2009 #11

是否可以以可以传入无效参数或不存在的变量的方式编写函数,并且 php 在不使用“@”的情况下不会出错

是的你可以!

porneL是正确的[编辑:我没有足够的积分链接到他的答案或投票,但它在这个页面上]

当他警告说“但我建议不要滥用它来隐藏编程错误”时,他也是正确的。 但是,出于同样的原因,也应该避免通过错误控制运算符(@)进行错误抑制。

我是 Stack Overflow 的新手,但我希望错误答案在页面上排名最高而正确答案没有投票的情况并不常见。:(

评论

0赞 Gerry 6/5/2009
我现在有足够的点可以直接链接到 porneL 的答案: stackoverflow.com/questions/55060/884770#answer-311954 很高兴看到随着时间的推移,事情开始在 stackoverflow 线程上出现转机,积分最终会分配给正确的人。:)遗憾的是,这个帖子已经被浏览了 753 次,人们可能错过了 porneL 的帖子(该帖子位于底部,票数为零),而是看到了错误的答案。
0赞 BraedenP 5/31/2009 #12

如果只是向参数添加默认值,则可以在调用函数时跳过它。例如:

function empty($paramName = ""){
    if(isset($paramName){
        //Code here
    }
    else if(empty($paramName)){
        //Code here
    }
}
3赞 Bob Fanger 12/8/2009 #13

在某些情况下,检查变得繁琐和不方便。
因此,我写了这个小小的魔术函数:

/**
 * Shortcut for getting a value from a possibly unset variable.
 * Normal:
 *   if (isset($_GET['foo']) && $_GET['foo'] == 'bar') {
 * Short:
 *   if (value($_GET['foo']) == 'bar') {
 *
 * @param mixed  $variable 
 * @return mixed  Returns null if not set
 */
function value(&$variable) {
    if (isset($variable)) {
        return $variable;
    }
}

它不需要对 myHappyFunction() 进行任何更改。
你必须改变

myHappyFunction($someBogusVar);

myHappyFunction(value($someBogusVar));

明确说明您的意图。这在我的书中是很好的实践

0赞 Omar 6/5/2012 #14

使用一行,您可以编译它:myHappyFunction($someBogusVar="");

我希望这就是你要找的。如果您阅读 php 文档,在默认参数值下,您可以看到为函数的参数分配默认值有助于防止在使用函数时出现错误消息。

在此示例中,您可以看到使用默认参数的区别及其优点:

PHP代码:

<?php
function test1($argument)
{
    echo $argument;
    echo "\n";
}

function test2($argument="")
{
    echo $argument;
    echo "\n";
}

test1();
test1("Hello");
test1($argument);
$argument = "Hello world";
test1($argument);

test2();
test2("Hello");
test2($argument);
$argument = "Hello world";
test2($argument);
?>

test1() 行的输出:

警告:缺少 test1() 的参数 1。
你好。

世界您好。

test2() 行的输出:

.
你好。

世界您好。

这也可以与其他功能组合使用,以完成您想要的功能。isset()