错误控制运算符

PHP 支持一个错误控制运算符:@。当将其放置在一个 PHP 表达式之前,该表达式可能产生的任何错误信息都被忽略掉。

如果激活了 track_errors 特性,表达式所产生的任何错误信息都被存放在变量 $php_errormsg 中。此变量在每次出错时都会被覆盖,所以如果想用它的话就要尽早检查。

<?php
/* Intentional file error */
$my_file = @file ('non_existent_file') or
    die (
"Failed opening file: error was '$php_errormsg'");

// this works for any expression, not just functions:
$value = @$cache[$key];
// will not issue a notice if the index $key doesn't exist.

?>

注: @ 运算符只对表达式有效。对新手来说一个简单的规则就是:如果能从某处得到值,就能在它前面加上 @ 运算符。例如,可以把它放在变量,函数和 include() 调用,常量,等等之前。不能把它放在函数或类的定义之前,也不能用于条件结构例如 ifforeach 等。

参见 error_reporting() 及手册中错误处理及日志函数的有关章节。

警告

目前的“@”错误控制运算符前缀甚至使导致脚本终止的严重错误的错误报告也失效。这意味着如果在某个不存在或类型错误的函数调用前用了“@”来抑制错误信息,那脚本会没有任何迹象显示原因而死在那里。


add a note add a note User Contributed Notes
programming at kennebel dot com
13-Oct-2006 09:38
To suppress errors for a new class/object:

<?php
// Tested: PHP 5.1.2 ~ 2006-10-13

// Typical Example
$var = @some_function();

// Class/Object Example
$var = @new some_class();

// Does NOT Work!
//$var = new @some_class(); // syntax error
?>

I found this most useful when connecting to a
database, where i wanted to control the errors
and warnings displayed to the client, while still
using the class style of access.
me at hesterc dot fsnet dot co dot uk
04-Mar-2005 12:25
If you wish to display some text when an error occurs, echo doesn't work. Use print instead. This is explained on the following link 'What is the difference between echo and print?':

http://www.faqts.com/knowledge_base/view.phtml/aid/1/fid/40

It says "print can be used as part of a more complex expression where echo cannot".

Also, you can add multiple code to the result when an error occurs by separating each line with "and". Here is an example:

<?php
$my_file
= @file ('non_existent_file') or print 'File not found.' and $string = ' Honest!' and print $string and $fp = fopen ('error_log.txt', 'wb+') and fwrite($fp, $string) and fclose($fp);
?>

A shame you can't use curly brackets above to enclose multiple lines of code, like you can with an if statement or a loop. It could make for a single long line of code. You could always call a function instead.
frogger at netsurf dot de
27-Dec-2004 12:19
Better use the function trigger_error() (http://de.php.net/manual/en/function.trigger-error.php)
to display defined notices, warnings and errors than check the error level your self. this lets you write messages to logfiles if defined in the php.ini, output
messages in dependency to the error_reporting() level and suppress output using the @-sign.
webmaster __AT__ digitalanime __DOT__ nl
19-May-2004 06:10
Someone over here wanted to know how to use the @ in your error handler... It's easy:

<?php
function my_error_handler(.......)
{
  if(
error_reporting() == 0) // error_reporting() = 0, so it was called with @ in front of it
 
{
  
// do nothing
 
}
  else
  {
  
// do something
 
}
}
?>
manicdepressive at mindless dot com
29-Feb-2004 08:44
taking the value of a non existant element:

   $foo = @$array['not_here']

will work as described, setting $foo to NULL,

but taking a *reference* to a non-existant element:

   $foo =& @$array['not_here']

will create the element with a NULL value, which $foo will then referece.

  -- code till dawn, mark meves
sdavey at datalink dot net dot au
30-Nov-2003 08:26
To suppress error warnings for functions that use the error operator '@' in your own error handlers, I found a sentence on the set_error_handler() page that explains it:
http://www.php.net/manual/en/function.set-error-handler.php

To paraphrase, it says that PHP temporarily sets the value of error_reporting() to 0 when in the error handler.

So, if you have the following:

$fp = @fopen("non-existent-file", "r");

when your custom error handler function is called, you can check the value of error_reporting() like this:

function handler($type, $str, $file, $line, $info) {
   // don't respond to the error if it
   // was suppressed with a '@'
   if (error_reporting() == 0) return;

   // otherwise, handle the error
   ...
}
john-at-n0-spam-foobar-dot-nl
26-Jul-2003 01:04
With set_error_handler() you bypass the standard error handler, which takes care of @.

if (!($fp = @fopen('not_a_file', 'r')))
  trigger_error("Can't open file!", E_USER_WARNING);

... generates ...

Warning: fopen("not_a_file", "r") - No such file or directory in index.php on line 19.
User Warning : Can't open file! in index.php on line 20.

... when I use my own error handler. With the standard error handler I only get the second warning.

If someone knows how to use @ with your own error handler, let me know.
psychohist at aol dot com
05-Jul-2003 04:59
if you create a new variable by assigning to it the error
suppressed value of an unset variable, the new variable
will be set, with a value of (I believe) null:

$new_variable                // previously not set
   = @$nonexistent_variable; // also not set

$next_variable = $new_variable // no warning generated
25-Apr-2003 09:24
It should be noted that suppressed error reporting is inherited, so to speak.

Consider this function:
function warning() {
   $return = 10 / 0;
   return $return;
}

This line will produce a warning;
var_dump(warning());

While these will not:
var_dump(@warning());
@var_dump(warning());

This might not be so obvious for some people; I know I didn't expect this behaviour.
20-Oct-2002 02:00
To suppress errors for a method inside a class, place the @ operator before the object and not before the method name.

// DO:
@$this->foo($bar);

// DON'T:
$this->@foo($bar);
drm at gerard dot yoursite dot nl
21-Aug-2002 06:50
When you check if an index of an array is set, you imply that the array itself already exists.

So
if ( isset ( $array [ 'index' ] ) ) {
}

would generate a notice if $array is not defined, but not if $array _is_ defined, but the index 'index' not.

And so on for nested arrays ofcourse
webmaster at speedy dot co dot il
07-Jul-2002 08:31
I don't know if this is a feature or bug, but this doesn't work:

if (!(isset(@$GLOBALS['SPEEDY_GLOBAL_VARS']['PAGE_NAME'])))

On the other hand, this works:

if (!(@isset($GLOBALS['SPEEDY_GLOBAL_VARS']['PAGE_NAME'])))

Regards,
Uri.