2011-02-19 42 views
6

最佳实践,我发现自己这个做了很多:PHP:无提示失败

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

一样,几乎每当我处理阵列。我习惯于JavaScript和简单检查虚假价值的能力。但是,这在PHP中是否合适?我是否试图强制PHP成为我已经理解的东西,而不是将它学习为自己的语言?

编辑

我udnerstand,我可以只使用isset(我也* *下忍受了),但它笨重的感觉对我来说,这导致在那里我想呼应,甚至笨重的情况值:

// 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 '" />'; 

抛开卫生问题,我更喜欢第一个版本。但我有一个偷偷摸摸的怀疑,这是一个很大的禁忌。 (我也有一个鬼鬼祟祟的怀疑,我不知道如何拼写“的嫌疑。”)

+1

关于您的编辑:我想你想做的事就好了。一个不存在的'$ values ['whatever']'会出现为空值并被转换为空字符串。错误抑制的范围是有限的,它不会隐藏你需要看到的错误。 – awm

回答

11

我建议NEVER使用@运算符。它鼓励糟糕的代码,当某些事情不起作用并且您正在尝试调试时,可能会使您的生活变得悲惨。

你当然可以在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

这是真的,我今天做了@ $ _ GET [sef :: VAR_NAME],并且php不会告诉我我做错了什么(自我不是sef !!!)。 – fabio

+0

嗨法比奥 - 如果你在你的PHP类中引用了一个实例变量,你会想用这个:$ myValue = $ this-> VAR_NAME;要与上面的海报一起使用,这就足够了:$ myValue =(isset($ _GET [$ this-> VAR_NAME]))? $ _GET [$ this-> VAR_NAME]:'空字符串'; –

+0

SELF关键字将用于引用您的PHP类中的静态函数(即SELF :: quote_string('quote this');) –

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

但是如果他只想抑制脚本特定部分的错误怎么办?关闭所有错误并不总是可取的。 – fabio

+2

@fabio:在特定部分隐藏错误称为“错误”;)如果你想到了,你需要它,而不是真的应该考虑一下,那个部分可能会有些问题。 – KingCrunch

+1

@fabio:它不关闭erorrs,它只是确定是否应该在屏幕上打印错误。 –

2

为什么你想抑制一些不会发生的事情,如果你在访问数组之前检查数组?

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

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

但是,只要你可以避免这种情况(并且真的有很少的情况,你无法避免它),那么@-操作者绝不是一个好主意。它也很不起作用。

+0

'array_key_exists'对此没有用处。永远不会存在一个值为NULL的键。这都是弦乐。 – mario

+0

我完全同意在几乎所有情况下都应避免使用@,但这是使用'@'的时候**的最佳例子。 '$ something = @ $ _GET ['else']'比条件表达式更容易阅读(imho),并产生相同的结果。 – awm

+0

性能部分实际上让我担心它。 – sdleihssirhc

1

我之前提到过,并很高兴地说了一遍:

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

等同于:

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

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

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

$else = $_GET["else"]; 

关闭调试通知,而你不需要它们。 (实际上我通常也使用愚蠢的isset()方法,但我使用的是面向对象的超级全局变量,而不是PHP4风格的$ _POST和$ _GET数组,所以它只是一个隐藏的isset(),并且不会运行t污染我的代码。)

0

这是一个常见问题,虽然解决方案很简单,但你说得对,它并不漂亮。我个人喜欢用包装纸。你可以非常容易地编写一个简单的类来实现ArrayAccess,通过包装传入的数组来完成。它会在内部(在一个地方)执行密钥检查,并且在询问不存在的密钥时悄悄地返回null。结果看起来像这样:

'bar')); var_dump($ arr ['foo']); var_dump($ arr ['zing']); //串(3)“栏中的” // NULL ?>

这也可能会觉得你更熟悉,从Javascript来了,你可以给类添加新的功能,以及像自定义排序,或者可能是过滤。

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), '" />' 
;