PHP:无声失败的最佳实践

时间:2011-02-19 00:59:18

标签: php

我发现自己做了很多这样的事情:

$something = @$_GET['else'];
if ($something) {
    // ...
} else {
    // ...
}

就像,几乎每当我处理数组时。我已经习惯了JavaScript和简单检查虚假价值的能力。但这在PHP中是否合适?我是否试图强迫PHP成为我已经理解的东西,而不是将其作为自己的语言学习?

修改

我认为我可以使用isset(我也*站在它下面),但它对我来说很笨拙,并且它导致甚至笨拙的情况,我试图回应价值:< / p>

// what I want to do
echo '<input type="text" name="whatever" value="', @$values['whatever'], '" />';

// what I fear I must do
echo '<input type="text" name="whatever" value="';
if (isset($values['whatever'])) {
    echo $values['whatever'];
}
echo '" />';

撇开卫生问题,我更喜欢第一个版本。但我有一种潜在的怀疑,认为这是一个很大的禁忌。 (我也怀疑我不知道如何拼写“怀疑”。)

6 个答案:

答案 0 :(得分:11)

我建议使用@运算符从不。它会鼓励糟糕的代码,并且当某些东西不起作用而你正试图调试它时,会让你的生活变得悲惨。

你当然可以在php.ini中禁用通知,但如果我是你,我会开始使用isset()更多:)

您可以这样做:

echo '<input type="text" name="whatever" value="', (isset($values['whatever'])?$values['whatever']:''), '" />';

您可以在此处详细了解@是多么可怕,http://php.net/manual/en/language.operators.errorcontrol.php

嗯,实际的错误触发是昂贵的。使用@会触发错误。用isset()来检查,不是。 http://seanmonstar.com/post/909029460/php-error-suppression-performance

答案 1 :(得分:7)

回答标题:最好的方法是turn off display_errors

对于您的具体操作,请使用isset()

注意:对于那些抱怨“关闭”所有错误的人 - from the PHP manual

  

这是一项支持您的开发的功能,不应在生产系统上使用(例如连接到互联网的系统)。

编辑之后:您可以确保您要使用的变量具有某些值(只是盲目地回显get / post var不是最佳实践) - 或者您可以使用一个对象来存储您想要输出的变量(作为属性),并在未设置属性时使用__get()返回一个空字符串(或false)。

这会让你有类似的东西:

echo $view->something;
if($view->something){
   //stuff to do when something is set
}

我相信这与许多模板/视图库的功能类似。

更新:注意到这个旧的(ish)答案,并认为可以添加一些东西。对于此用例(值可能在数组中,也可能不在数组中),可以使用array_merge()

$default = array('user' => false);
$params = array_merge($default, $_GET);
if($params['user']){ //safe to use, will have default value if not in $_GET

}

答案 2 :(得分:2)

如果在访问数组之前检查数组,为什么要压制某些不会发生的事情呢?

$something = array_key_exists('else', $_GET) ? $_GET['else'] : null;
$something = isset($_GET['else']) ? $_GET['else'] : null;

你的方式似乎只是懒惰的解决方案。

但是,@ - 运算符永远不是一个好主意,只要你可以避免它(并且实际情况非常少,你无法避免它)。它也非常难以理解。

答案 3 :(得分:2)

使用通用函数进行数组访问:

/**
 * Function for accessing array elements and returning a
 * default value if the element is not set or null.
 * @param string $key Name of index
 * @param array $array Reference to an array
 * @param string $default Value to return if the key is not
 *        found in the array
 * @return mixed Value of array element (if it exists) or whatever
 *        is passed for default.
 */
function element( $key, &$a, $default = '' )
{
    if( array_key_exists( $key, $a ) && !is_null( $a[$k] ) )
    {
        return $a[$key];
    }
    return $default;
}

然后您的HTML输出可能如下所示:

echo '<input type="text" name="whatever" value="'
   , element( 'whatever', $values ), '" />'
;

答案 4 :(得分:1)

我以前说过,很高兴再说一遍:

$else = isset($_GET['else']) ? $_GET['else'] : null;

相当于:

$else = @$_GET["else"];

不同之处在于,由于语法盐的错误抑制而导致可读性较差,而另一个则使用预期的语言功能。另请注意,在第二种情况下,通知(许多人不理解错误的区别)仍然可以被自定义处理程序发现。

出于所有实际目的,你不应该使用。使用简单:

$else = $_GET["else"];

在不需要时关闭调试通知。

(实际上我通常也使用哑isset()方法。但我使用面向对象的超全局,而不是PHP4风格的$ _POST和$ _GET数组,所以它只是一个隐藏的isset()并且不会污染我的代码。)

答案 5 :(得分:0)

这是一个常见问题,虽然解决方案很简单,但你说它并不漂亮。我个人喜欢用包装纸。通过包装传入的数组,您可以非常轻松地编写一个实现ArrayAccess的简单类。它将在内部(在一个地方)进行密钥检查,并在被要求输入不存在的密钥时安静地返回null。结果看起来像这样:

 '酒吧')); 的var_dump($ ARR [ '富']); 的var_dump($ ARR [ '诚']); // string(3)“bar” // 空值 ?&GT;

对于您来说,这可能会让您感觉更熟悉,因为您可以为类添加新功能,例如自定义排序或过滤。