PHP中的'@'前缀有什么作用?

38

在以下代码中,'@'符号是什么作用?

@mkdir(ROOT. "cache/");

14
好的。请尝试在 PHP 网站上搜索“@”或“@前缀” - 这会让你走得更远。不是这样的。 - Rich Turner
3
这个运算符被老练的 PHP 开发者亲切地称为“stfu”运算符。;-) - Uwe Keim
@Rich Turner - 在当前的PHP网站上搜索@和@前缀什么都没有找到 :-( - undefined
3个回答

42

它抑制了错误的显示

PHP支持一个错误控制运算符:at符号(@)。当在PHP中的表达式前加上at符号时,该表达式可能生成的任何错误消息都将被忽略。

如果启用了track_errors功能,由该表达式生成的任何错误消息都将保存在变量$php_errormsg中。每次出现错误时,该变量都会被覆盖,所以如果要使用它,请尽早检查。

正如评论中所指出的,我也无法想象出实际使用这个功能的理由 - 编写能够适当处理错误状态/条件的代码。


1
谢谢你的回答。这让我继承的那些令人讨厌的代码变得比我想象的还要糟糕! - Rich Turner
因为调试会非常困难,所以尽量避免使用此功能,特别是在关键代码上。 - Xavier Barbosa
1
在循环中使用@符号时要小心:每次运行都会触发error_reporting()两次。最好在循环前禁用错误,然后在循环完成后重置错误级别。 - xrstf
在某些孤立的情况下,它可能很有用,当您还设置了一个抛出异常的错误处理程序(例如将错误消息转换为 ErrorException 的错误处理程序)。您可以使用 @ 而不是使用 try/catch,并检查返回值是否为错误情况。当然,如果所有代码都在同一个代码库中,您只需要使用一种类型的错误处理方式,但是当涉及到多个库时,这可能是唯一的可行方式。 - Ludovic Chabant
一个使用 @ 错误抑制符号可能有用的实例是在寻找具有 fopen($file, 'x') 的唯一文件名的情况下,如果已经存在该名称的文件,则会产生 E_WARNING 错误。 - Brian C
显示剩余5条评论

8
如上所指出,它是错误抑制运算符。
然而,未指出的是,使用它是非常糟糕的做法——错误不应该默默失败。
检查错误返回并在使用异常时使用try/catch块。
在具体的例子中...
@mkdir(ROOT. "cache/");

...它忽略了mkdir()中的任何错误。 文档说明它在失败时返回FALSE,因此您应该进行...

if ( ! mkdir(ROOT. "cache/")) {
   // Handle error.
}

7

人们似乎忘记了PHP最初是一种快速而粗略的语言,仅最近开始尝试变得成熟和复杂。

错误抑制是一种快速而粗略的方法,可以使函数按照您需要的方式运行。因为在Web开发中,您无法预测会遇到什么,有时候也不值得关心!

一个经典的例子是有用的getimagesize函数,它允许您获取有关某个人上传的图像的一些信息。 如果图像文件不是标准图像文件,此函数会出现错误。开发人员并不真正扮演检查文件、确定它是否可以加载到getimagesize中的角色。可能有优雅的方法来解决这个问题,但我并不在意!

只需执行以下操作:

if( !($a = @getimagesize(  $_FILE['file']['tmp_name'] )))
{
   unlink( $_FILE['file']['tmp_name'] );

   //politely tell user that you rejected their image!
}

是的,您可以使用更加优雅的try和catch语句,但最终,您已经捕获了错误并抑制了错误消息,这正是您想要的,而不会耗尽Tab键!

与上面的答案所说的相反,小心使用@前缀不会导致失控的灾难。它只允许开发人员根据自己的喜好处理错误。


开启 PHP 的提示信息后,我认为 @ 抑制符变得非常有用,例如: if( @$_POST['submit'] == 'send' ){} - Gordon Rouse
可能有更优雅的方法来做这件事,但是说实话我不在乎!希望我永远不会碰你的代码。 - Gabriel
我真的很喜欢这个答案。我对PHP还很陌生,很容易意外生成不想让用户看到的错误。这个运算符似乎是一个简单的解决方法。 - I_ATE_YOUR_WORK_FILES
很容易意外生成不希望用户看到的错误。 - Gordon Rouse
抱歉,试图说“很容易意外生成不想让用户看到的错误”并不是使用@符号的原因。您仍然需要对条件负责。 - Gordon Rouse
好的 - 我有点自相矛盾,是的,它确实可以抑制警告,但只有在你知道自己在做什么的情况下使用它! - Gordon Rouse

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接