PHP函数参数错误抑制,Empty()isset()仿真

时间:2020-03-05 18:51:01  来源:igfitidea点击:

我很确定这个问题的答案是否定的,但是如果有一些PHP专家

是否有可能编写一种函数,使其可以传入无效的参数或者不存在的变量,并且在不使用'@'的情况下php不会出错。

就像empty和isset一样。我们可以传入一个刚创建的变量,它不会出错。

ex:

empty($someBogusVar); // no error

myHappyFunction($someBogusVar); // Php warning / notice

解决方案

回答

不,因为这实际上与该功能无关。该错误来自尝试取消引用不存在的阵列键。我们可以更改PHP设置的警告级别以消除这些错误,但是最好不要这样做。

话虽如此,我们可以做类似的事情

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

  return 0;
}

并使用它代替数组键查找

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

现在我要洗个澡:)

回答

@Brian: I use a trinary operation to do the check for me:
return $value ? $value : $default;

这将返回$ value或者$ default。取决于$ value的值。如果为0,false,空或者类似的内容,则将返回$ default中的值。

我更倾向于挑战像empty()和isset()这样的函数

回答

进一步深入到抽象树,我们将其用于什么?

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

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,但是如果需要对输出进行一些修改或者对输入进行验证,它们也将有助于维护。

回答

我敢肯定,关于三元运算符vrs函数调用的讨论可能会很精彩。但是这个问题的重点是看是否可以创建一个函数,如果不使用'@'传递不存在的值,则不会抛出错误

回答

我们可以像这样使用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";

此函数进一步走了一步,将为我们提供任意数量的args的第一个非空值(我们可以始终强制它最多使用两个args,但这对我来说似乎更有用)。

编辑:原始版本没有使用compact来尝试使args数组和STILL给出了错误。错误报告增加了一个缺口,这个紧凑的新版本虽然没有那么整洁,但是仍然可以做同样的事情,并且允许我们为不存在的var提供默认值。

回答

@Sean布莱恩已经回答了

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

回答

肖恩,我们可以这样做:

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

编辑:

I'm sure there could be a great
  discussion on ternary operators vrs
  function calls. But the point of this
  question was to see if we can create a
  function that won't throw an error if
  a non existent value is passed in
  without using the '@'

我告诉过我们,请使用isset()进行检查。三元条件的第一部分不检查null或者不为null,而是检查true或者false。如果我们尝试在PHP中为空值检查" true"或者" false",则会收到这些警告。 isset()检查变量或者表达式是否返回空值,并返回一个布尔值,可以由三元组的第一部分对其进行求值而没有任何错误。

回答

总结一下,正确的答案是"不,我们不应该"(请参阅​​下面的警告)。

该线程中已经有很多人提到过一些变通方法,例如在条件中使用引用变量或者isset()或者empty()并禁止PHP配置中的通知。除了明显的解决方法之外,我们还不需要使用@。

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

回答

通过引用传递变量时,我们不会收到任何错误(PHP将以静默方式创建新变量):

function myHappyFunction(&$var)
 {       
 }

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

回答

尽管对原始问题的回答是"否",但没有人提到任何选择。

当我们使用@符号时,所有PHP所做的就是覆盖error_reporting级别并将其暂时设置为零。我们可以使用"ini_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;
     }
}

因此,在上述情况下,如果未设置$ bar,则在使用不存在的变量调用foo()时不会出错。但是,从错误输入is_set而不是isset的函数中会出现错误。

这可能是一个有用的选项,可以覆盖原始问题的实质内容(如果不是实际情况)。

回答

is it possible to write a function in a way where invalid arguments or non existent variables can be passed in and php will not error without the use of '@'

是的你可以!

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

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

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

回答

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

function empty($paramName = ""){
    if(isset($paramName){
        //Code here
    }
    else if(empty($paramName)){
        //Code here
    }
}

回答

在某些情况下,检查变得麻烦而不必要。
因此,我编写了这个小魔术函数:

/**
 * 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));

明确说明意图。这是我的书中的最佳做法。