set_error_handler

(PHP 4 >= 4.0.1, PHP 5)

set_error_handler --  Sets a user-defined error handler function

说明

mixed set_error_handler ( callback error_handler [, int error_types] )

Sets a user function (error_handler) to handle errors in a script.

This function can be used for defining your own way of handling errors during runtime, for example in applications in which you need to do cleanup of data/files when a critical error happens, or when you need to trigger an error under certain conditions (using trigger_error()).

It is important to remember that the standard PHP error handler is completely bypassed. error_reporting() settings will have no effect and your error handler will be called regardless - however you are still able to read the current value of error_reporting and act appropriately. Of particular note is that this value will be 0 if the statement that caused the error was prepended by the @ error-control operator.

Also note that it is your responsibility to die() if necessary. If the error-handler function returns, script execution will continue with the next statement after the one that caused an error.

The following error types cannot be handled with a user defined function: E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING, and most of E_STRICT raised in the file where set_error_handler() is called.

If errors occur before the script is executed (e.g. on file uploads) the custom error handler cannot be called since it is not registered at that time.

参数

error_handler

The user function needs to accept two parameters: the error code, and a string describing the error. Then there are three optional parameters that may be supplied: the filename in which the error occurred, the line number in which the error occurred, and the context in which the error occurred (an array that points to the active symbol table at the point the error occurred). The function can be shown as:

handler ( int errno, string errstr [, string errfile [, int errline [, array errcontext]]] )

errno

The first parameter, errno, contains the level of the error raised, as an integer.

errstr

The second parameter, errstr, contains the error message, as a string.

errfile

The third parameter is optional, errfile, which contains the filename that the error was raised in, as a string.

errline

The fourth parameter is optional, errline, which contains the line number the error was raised at, as an integer.

errcontext

The fifth parameter is optional, errcontext, which is an array that points to the active symbol table at the point the error occurred. In other words, errcontext will contain an array of every variable that existed in the scope the error was triggered in.

error_types

Can be used to mask the triggering of the error_handler function just like the error_reporting ini setting controls which errors are shown. Without this mask set the error_handler will be called for every error regardless to the setting of the error_reporting setting.

返回值

Returns a string containing the previously defined error handler (if any), or FALSE on error. If the previous handler was a class method, this function will return an indexed array with the class and the method name.

更新日志

版本说明
5.0.0 The error_types parameter was introduced.
4.3.0 Instead of a function name, an array containing an object reference and a method name can also be supplied as the error_handler.
4.0.2 Three optional parameters for the error_handler user function was introduced. These are the filename, the line number, and the context.

范例

例子 1. Error handling with set_error_handler() and trigger_error()

The example below shows the handling of internal exceptions by triggering errors and handling them with a user defined function:

<?php
// set the error reporting level for this script
error_reporting(E_USER_ERROR | E_USER_WARNING | E_USER_NOTICE);

// error handler function
function myErrorHandler($errno, $errstr, $errfile, $errline)
{
  switch (
$errno) {
  case
E_USER_ERROR:
    echo
"<b>My ERROR</b> [$errno] $errstr<br />\n";
    echo
"  Fatal error in line $errline of file $errfile";
    echo
", PHP " . PHP_VERSION . " (" . PHP_OS . ")<br />\n";
    echo
"Aborting...<br />\n";
    exit(
1);
    break;
  case
E_USER_WARNING:
    echo
"<b>My WARNING</b> [$errno] $errstr<br />\n";
    break;
  case
E_USER_NOTICE:
    echo
"<b>My NOTICE</b> [$errno] $errstr<br />\n";
    break;
  default:
    echo
"Unkown error type: [$errno] $errstr<br />\n";
    break;
  }
}

// function to test the error handling
function scale_by_log($vect, $scale)
{
  if (!
is_numeric($scale) || $scale <= 0) {
    
trigger_error("log(x) for x <= 0 is undefined, you used: scale = $scale", E_USER_ERROR);
  }

  if (!
is_array($vect)) {
    
trigger_error("Incorrect input vector, array of values expected", E_USER_WARNING);
    return
null;
  }

  for (
$i=0; $i<count($vect); $i++) {
    if (!
is_numeric($vect[$i]))
      
trigger_error("Value at position $i is not a number, using 0 (zero)", E_USER_NOTICE);
      
$temp[$i] = log($scale) * $vect[$i];
    }
    return
$temp;
  }

// set to the user defined error handler
$old_error_handler = set_error_handler("myErrorHandler");

// trigger some errors, first define a mixed array with a non-numeric item
echo "vector a\n";
$a = array(2,3, "foo", 5.5, 43.3, 21.11);
print_r($a);

// now generate second array, generating a warning
echo "----\nvector b - a warning (b = log(PI) * a)\n";
$b = scale_by_log($a, M_PI);
print_r($b);

// this is trouble, we pass a string instead of an array
echo "----\nvector c - an error\n";
$c = scale_by_log("not array", 2.3);
var_dump($c);

// this is a critical error, log of zero or negative number is undefined
echo "----\nvector d - fatal error\n";
$d = scale_by_log($a, -2.5);

?>

上例的输出类似于:

vector a
Array
(
    [0] => 2
    [1] => 3
    [2] => foo
    [3] => 5.5
    [4] => 43.3
    [5] => 21.11
)
----
vector b - a warning (b = log(PI) * a)
<b>WARNING</b> [1024] Value at position 2 is not a number, using 0 (zero)<br />
Array
(
    [0] => 2.2894597716988
    [1] => 3.4341896575482
    [2] => 0
    [3] => 6.2960143721717
    [4] => 49.566804057279
    [5] => 24.165247890281
)
----
vector c - an error
<b>ERROR</b> [512] Incorrect input vector, array of values expected<br />
NULL
----
vector d - fatal error
<b>FATAL</b> [256] log(x) for x <= 0 is undefined, you used: scale = -2.5<br />
Fatal error in line 36 of file trigger_error.php, PHP 4.0.2 (Linux)<br />
Aborting...<br />


add a note add a note User Contributed Notes
mail at chernousov dot com
24-Oct-2006 06:52
When fatal error occurs, class destructors are not executed.

<?

class someClass {
  function
__construct() {
   echo
'__construct()';
  }

  function
__destruct() {
   echo
'__destruct()';
  }
}

$someClass = new someClass();
someNonExistentFunction();

?>

Result will be:

__construct()
Fatal error: Call to undefined function someNonExistentFunction() in tes.php on line 14
alexey.kupershtokh.gmail
02-Oct-2006 03:07
2errd
I've got more convenient and safe error to exception converter:

class CustomException extends Exception {
  public static function errorHandlerCallback($code, $string, $file, $line, $context) {
   $e = new self($string, $code);
   $e->line = $line;
   $e->file = $file;
   throw $e;
  }
}
set_error_handler(array("CustomException", "errorHandlerCallback"), E_ALL);
dk at brightbyte dot de
28-Aug-2006 07:09
Sometimes, you want to "catch" only some errors, and let the default handler deal with the result. I just found out that (at least in PHP 5), the default handler will be called if you return false (not 0 or NULL or '', but false) from your custom handler. This allows for "chaining" handlers.

The fature was suggested in this thread:
http://www.zend.com/lists/php-dev/200405/msg00491.html - the initial suggestion was to call the default handler if true is returned, but this was changed later on, apperently.
jla
28-Jul-2006 07:16
Other option to "handle" ALL errors

set_error_handler("yourHandler");

// Parse,Compile, Core, etc... Errors
ini_set('html_errors',false);
ini_set('error_prepend_string','<html><head><META http-equiv="refresh" content="0;URL=/error.php?msg=');
ini_set('error_append_string','"></head></html>');
kariedoo
08-May-2006 04:07
function errorlog($type, $info, $file, $row)
{
   if ($handle = fopen("./log/ftp_error.log", "a"))
   {
     @fwrite($handle, date("Y-m-d H:i:s")." "--> $type: $info FILE: $file -  Row $row\r\n" );
     @fclose($handle);
   }//end if
}//end function

### in the error logging code for example ftp: ###

set_error_handler("errorlog");  //set your own Handler
 
$this->connect = ftp_connect(TXTCONNECT);
$this->login = ftp_login($this->connect, TXTID, FTPPASS);
$this->systype= ftp_systype($this->connect);

restore_error_handler(); //restore the old handler

------------------
content in file
------------------

2006-05-08 09:36:02 2: ftp_login(): Login incorrect. FILE: /html/cgi-bin/test/classes/ftp.class.php - Row 63
docey
06-Apr-2006 03:50
if you wan't to know the current error-handler
set use something like this:

$current_errorhandler = set_error_handler("myerrorhandler");
restore_error_handler();

this will set your custom error_handler and return
the name of the previous set error handler. by
calling restore_error_handler, you remove your
custom error_handler and set the error_handler that
was set back again.

this way you can also switch back to php-default error-handler
without knowing how many error-handler already
are set, by using a loop till an empty string is
returned. because an empty string means
"no error-handler set" wich means php's default
errorhandler is set back.

like in this code below:

function restore_phperrorhandler()
{
 // get current error handler.
 $previous_errorhandler =
 set_error_handler("myerrorhandler");
 restore_error_handler();

 $max_loops = 20;
 $cur_loops = 0;
    
 // if current error handler is not already php's or fails.
   if(($previous_errorhandler != NULL) OR
     ($previous_errorhandler != "")){
  
       while($previous_errorhandler != ""){
         $cur_loops = $cur_loops + 1;
            
           // check if not exceeding infinit loop.
           if($cur_loops >= $max_loops){
             trigger_error("Restoring exceeds max. loops.",
             E_USER_WARNING);
             return false;
           }
        
           //switch to previous handler.
           restore_error_handler();
        
           // get its name and switch to it again.
           $previous_errorhandler =
           set_error_handler("myerrorhandler");
           restore_error_handler();
        
           // check if getting errorhandler failed.
           if($previous_errorhandler == NULL){
             trigger_error("Failed to get prev. error handler",
             E_USER_WARNING);
           return false;
            
           // empty string = php-default error handler
           }elseif($previous_errorhandler == ""){
             return true;
           }
       }
   }else{
     trigger_error("Current Error-Handler is default.",
     E_USER_NOTICE);
     return true;
   }
}

this function will loop and return true when no
error handler is left. leaving php-default handler
in controll again. this is usefull if you want to
disable your own error-handler but be sure that
php's is handling your error's and not any other
error-handler.
errd
30-Jan-2006 09:52
In errors to exceptions conversion below I found some incorrect stuff. File and line properties of Exception point to line and file where Exception is thrown, but not where real error is occured.

Impoved errors to exceptions converting:
+ Fixed filename of exception handled
+ Fixed code line of exception handled

<?php

class CustomException extends Exception {
  
public function setLine($line) { 
      
$this->line=$line;
   }
    
  
public function setFile($file) {
      
$this->file=$file;
   }
}

function
exceptionsHandler($code, $string, $file, $line) { 
  
$exception=new CustomException($string, $code);
  
$exception->setLine($line);
  
$exception->setFile($file);
  
throw $exception;


set_error_handler('exceptionsHandler', E_ALL);

?>
24-Jan-2006 05:19
To honor the value of PHP's error_reporting() function, use:

<?
 
if( ($level & error_reporting()) == 0 ) return;
?>
Gulopine
06-Jan-2006 01:36
Also note that even though the documentation states "errcontext will contain an array of every variable that existed in the scope the error was triggered in," that is not the case for $this in an instantiated object, as of PHP 5.1.1.

<?php

function error_function($errno, $errstr, $errfile, $errline, $errcontext) {
  
print_r($errcontext);
}

set_error_handler('error_function');

class
test_class {
  
private $id;
  
   function
__construct($id) {
      
$this->id = $id;
      
trigger_error('Test error');
   }
}

$test = new test_class(5);

?>

Result:

Array
(
   [id] => 5
)

I discovered this when trying to write an error handler that would log the class the error occured in, as it was triggered from a function in a parent class extended by several individual classes.
ia [AT] zoznam [DOT] sk
22-Sep-2005 07:33
as reply to dawiddr at gmail dot com:

Be careful with this when using __autoload(). When there is some error during parsing the file included in __autoload() so an exception is thrown, it results in following error:

Fatal error:  Function __autoload(ClassName) threw an exception of type 'Exception' in /network/webroot/dev/test.php on line 121

It is because exceptions can't be thrown in __autoload().
See __autoload() documentation (http://www.php.net/autoload) and bug #31102 (http://bugs.php.net/bug.php?id=31102&edit=3)
florian at siweho dot de
23-Aug-2005 03:26
@ mmtache at yahoo dot com
you have to use
if(error_reporting() != 0){
   .... (yourOwnHandler)

instead of
if(error_reporting()){
   ....

in PHP5. then operations like this "@fopen" won't show an error-message
eregon at eregon dot info
03-Aug-2005 12:35
It is not possible to handle fatal errors with own handler. Even if you have set your own handler, fatal error will be always handled by PHP's default handler. The reason is the script may be in unstable state after fatal error occurence (details here: http://marc.theaimsgroup.com/?l=php-dev&m=97673386418430&w=2).
dawiddr at gmail dot com
06-Jul-2005 07:01
In PHP5, if you want to have exceptions thrown instead of normal errors - you could use an error handler, which throw exceptions:

<?php

function handler($errno, $errstr, $errfile, $errline)
{
   print
"Error handled!\n";
  
throw new Exception($errstr, $errno);
}

set_error_handler('handler');

try
{
   print
2 / 0; // simple error - division by zero
  
print "This will never be printed";
}
catch (Exception $e)
{
   print
"Exception catched:\n";
   print
"Code: ".$e->getCode()."\n";
   print
"Message: ".$e->getMessage()."\n";
   print
"Line: ".$e->getLine();
}

?>

Result:

Error handled!
Exception catched:
Code: 2
Message: Division by zero
Line: 6

As you see, exception is catched like it have been thrown by division by zero - in try/catch clause. But line numer and backtrace shows, that is was thrown by the error handler.
frank at ethisoft dot nl
01-Jun-2005 06:11
Perhaps it is worth mentioning that in
PHP5
both set_error_handler & set_exception_handler can be called with an array containing 2 arguments:
1) var  ==> object
2) string ==> name of handler function in object

EXAMPLE:
<?php
set_error_handler             
(array($object, 'handler_function'));
set_exception_handler      (array($object, 'handler_function'));
?>

Both can point to the same object and handler_function so that both error and exception handling, which are very much alike usually, can be done by only 1 dedicated class.
jgiglio at netmar dot com
26-Mar-2005 12:02
set_error_handler also overrides the default behavior of postgresql which is to shoot HTML errors to the browser on a query failure or other database error.

I can't find a list of symbolic $errno names for postgres errors, but a normal "bad query" throws an errno of 2.

Be careful to not use an empty default case in your errno case statement if you use postgresql, and expect php to generate DB errors automatically.
Steffen Staehle
12-Jan-2005 06:29
Two notes on using set_error_handler() on behaviour that I noticed when migrating an application from php 4.2.1 to php 4.3.9 (I do not yet have php 5.0 available, this might not apply there!).

1. setting the system error handler

If you want to set the standard php error handler again, after having set your own error handler, this works in php 4.2.1 by passing in an empty string:

<?php

  
function my_handler($log_level, $log_text, $error_file, $error_line)
   {
    
// if an error occurs here, the standard error
     // would be called (to avoid recursion)

     // do something useful
     // ...
  
}

  
$last_handler = set_error_handler("my_handler");

  
// after this, $last_handler == ""

   // restore standard error handler

  
$last_handler = set_error_handler("");

  
// after this, $last_handler == "my_handler"

?>

The very same code now raises an error in php 4.3.9:

   set_error_handler() expects argument 1, '', to be a valid callback

(Since the return value of the first call to set_error_handler() is still the empty string "", I don't see how this can be done any more. I don't really need this, because I use my own handlers as shown below, but it might be good to be aware of this.)

2. setting your own 'second level' handler

If you have set your own error handler, and want to replace it by another one (other than the standard php error handler) while it is being executed, note that the return value of set_error_handler when used INSIDE the error handler is "" instead of the name of the previous handler! This is not too surprising, because during execution of your self defined error handler, php replaces it with the standard php error handler to avoid infinite loops in case of problems inside the handler. This is only interesting if you want nested handlers as I do. Background of my design:

   1st level handler: log into DB
   2nd level handler: log into flat file (if log into DB fails)
   3rd level handler: print to stdout (if log into flat file fails) (this is the sytem handler, finally).

<?php

  
function my_fallback_handler($log_level, $log_text, $error_file, $error_line)
   {
    
// if an error occurs here, the standard error
     // would be called (to avoid recursion)

     // do something useful
     // ...

  
} // my_fallback_handler

  
function my_handler($log_level, $log_text, $error_file, $error_line)
   {
    
// if an error occurs here, the standard error
     // would be called (to avoid recursion)

     // but we want to have a fallback handler different
     // to the standard error handler

    
$last_handler = set_error_handler("my_fallback_handler");

    
// I expected $last_handler == "my_handler"
     // (which it would outside my_handler())
     // but here it is the empty string ""

     // do something useful
     // ...

     // now set the 1st level handler again:
     // (do NOT use $last_handler as argument,
     // because it equals "")

    
$last_handler = set_error_handler("my_handler");

   }
// my_handler

  
$last_handler = set_error_handler("my_handler");

?>
Sukender
10-Aug-2004 11:29
In PHP5, ou can ask for the default handler to be called after your custom handler by returning "false". See this pseudo-code :
<?
function MyHandler($errno, $errstr, $errfile, $errline, $errcontext) {
  
my_handling_code;        // Do something, such as sending an email to the admin
  
if (i_want_to_call_the_default_handler) return false;        // will invoke the default error handler just after
  
else return true;        // This will NOT invoke it (= you've properly handled the error)
}
set_error_handler("MyHandler");
?>

I have not tested the functionality, but I think that the php.ini directive "log_errors" keeps working, but *only* when you call the default handler (= retrun false).

>>> Source : Mailing list thread about "re-invoking default error handler" at http://www.zend.com/lists/php-dev/200405/msg00491.html (be careful about the first post : "true" and "false" are switched - because it's only a proposition).
Joe
30-Jun-2004 01:26
When a custom error handler is set, the php.ini directive "log_errors" stops working.  I'm guessing to favor your custom handler.  You can still log your errors with the "error_log" function, but it doesn't happen when you have a custom error handler.
Cezary Tomczak
22-Apr-2004 04:25
Here is a script to debug / display errors in a nice way: http://gosu.pl/demo/ErrorHandler/ErrorHandler.zip

Example of displaying an error: http://gosu.pl/demo/ErrorHandler/example1.html
Example of displaying source of the file where the error appeared: http://gosu.pl/demo/ErrorHandler/example2.html

Displaying error: generates a backtrace, show file / line, show function / arguments (and values), source of the file
erwin at isiz dot nl
19-Apr-2004 09:51
@sijmen at digitized dot nl
That's not true. The reference operator does have effect, when used correctly.

Your code doesn't use the reference operator in the set_error_handler function, but it does when creating the new error object. In your case, you have to use the reference operator two times.

When calling the set_error_handler function

<?php
       set_error_handler
(array(&$this, 'handler'));
?>

and when creating the class

<?php
$eh
= &new error;
?>

In that case the same error class will be used and the output will be following:
Error!
!!

Hope this helps.
mightye (at) mightye (dot) org
13-Apr-2004 05:18
You can't use this functionality to catch parse errors in included, required, or eval()'d code.  Parse errors seem to exist on a deeper level.
sijmen at digitized dot nl
09-Apr-2004 10:47
@jayp at groovejob dot com
As I said before, the reference operator doesn't have any effect on the the error handler.

Proof of concepts:
http://trouby.digitized.nl/set_error_handler2.php
http://trouby.digitized.nl/set_error_handler2.php?source=1
jayp at groovejob dot com
04-Apr-2004 01:28
In response to sijmen at digitized dot nl:

Instead of

$eh = new error;

use

$eh =& new error();

The new operator returns a copy of the error object, so the error handler that is set in the constructor is tied to a different object instance than the instance returned by "new".  To make sure you are working with the exact same object instance that you think you are, it's best to use the reference object when creating instances of objects, like so:

$oMyObject =& new MyObject();

HTH,

Jay
sijmen at digitized dot nl
30-Mar-2004 11:23
@skyrl at free dot fr
It seems that the reference operator '&' doesn't have any effect. That's why I submitted the comment.

<?php
class error {
   var
$error;

   function
error() {
      
$this->setIni();
   }

   function
handler() {
       echo
$this->error.'!!';
   }

   function
setText($text) {
        
$this->error = $text;
   }

   function
setIni() {
      
set_error_handler(array(&$this, 'handler')); // The '&' operator doesn't have any effect
  
}
}

$eh = new error;
$eh->setText('Error! <br>'); // Will not get set

trigger_error('text', E_USER_ERROR); // prints '!!'
?>

Proof of concept
http://trouby.digitized.nl/set_error_handler.php
http://trouby.digitized.nl/set_error_handler.php?source=1
skyrl at free dot fr
30-Mar-2004 11:00
in reaction to the last '29-Mar-2004 11:13' post, just have to say that's normal the values are not "saved" in your error handler object. because the error object of the handler is not the same object as the one you instantiate...

You have to write set_error_handler(array(&this, 'my_error_handler')). The & is important for php to know that your error handler belongs to the same instance you allocate.
30-Mar-2004 08:13
It seems that when you're letting PHP know that you have a custom  error handler, you're not able to -update/set new- variables inside the class. Example:

<?php
class error {
   var
$error;

   function
error() {
      
$this->setIni();    // this causes PHP to ignore all other changes to the class.
  
}

   function
handler() {
       echo
$this->error.'!!';
   }

   function
setText($text) {
        
$this->error = $text;
   }

   function
setIni() {
      
set_error_handler(array($this, 'handler'));
   }
}

$eh = new error;
$eh->setText('Error! <br>');  // this will not be saved

trigger_error('text', E_USER_ERROR);
// prints '!!'
?>

How it should be done:
<?php
class error {
   var
$error;

   function
error() {
        
// dont let PHP know of our error handler yet
  
}

   function
handler() {
       echo
$this->error.'!!';
   }

   function
setText($text) {
        
$this->error = $text;
   }

   function
setIni() {
      
set_error_handler(array($this, 'handler'));
   }
}

$eh = new error;
$eh->setText('Error! <br>');  // this WILL work
$eh->setIni();  // call this method when you're ready with configuring the class. All other methods that will be called will have no effect on the errorHandling by PHP

trigger_error('text', E_USER_ERROR);
// prints 'Error! <br>!!'
?>
phpmanual at NO_SPHAMnetebb dot com
16-Nov-2003 12:19
Given this code:

class CallbackClass {
   function CallbackFunction() {
       // refers to $this
   }

   function StaticFunction() {
       // doesn't refer to $this
   }
}

function NonClassFunction() {
}

there appear to be 3 ways to set a callback function in PHP (using set_error_handler() as an example):

1: set_error_handler('NonClassFunction');

2: set_error_handler(array('CallbackClass', 'StaticFunction'));

3: $o =& new CallbackClass();
   set_error_handler(array($o, 'CallbackFunction'));

The following may also prove useful:

class CallbackClass {
   function CallbackClass() {
       set_error_handler(array(&$this, 'CallbackFunction')); // the & is important
   }
  
   function CallbackFunction() {
       // refers to $this
   }
}

The documentation is not clear in outlining these three examples.
mlemos at acm dot org
21-Oct-2003 01:03
PHP does not really provide a way to catch all errors including parsing errors or for instance form file uploading errors.

Ideally, there should be a way to catch these errors and mail a system administrator so he can take immediate action.

The best you can do is to disable all output of errors to the pages and enable error logging to a file. Then you should take a look at this error log file periodically to figure what may be wrong.

The problem is that you can't just wait and sit there watching for errors in the log files until they happen. To solve this problem you may want to try this class that lets you watch a given error file periodically and mail the new log lines to a given address of the site  developer or system administrator.

http://www.phpclasses.org/logwatcher

It is like the Unix tail command except that you should run this from a cron task periodically (lets say, every 5 minutes). The class keeps track of the last log line that was read on each log file poll, so it knows where to resume checking the log file on the next time the cron task is run.
smp at ncoastsoft dot com
09-Sep-2003 06:28
Here is an example of catching ALL errors from php including parse and compile. This example comes from a web page referenced in another post (http://www.webkreator.com/cms/view.php/1692.html ). My example doesn't require any .htaccess editing at all:

function fatal_error_handler($buffer) {
  if (ereg("(error</b>:)(.+)(<br)", $buffer, $regs) ) {
   $err = preg_replace("/<.*?>/","",$regs[2]);
   error_log($err);
   return "ERROR CAUGHT check log file";
  }
  return $buffer;
}

function handle_error ($errno, $errstr, $errfile, $errline)
{
   error_log("$errstr in $errfile on line $errline");
   if($errno == FATAL || $errno == ERROR){
       ob_end_flush();
       echo "ERROR CAUGHT check log file";
       exit(0);
   }
}

ob_start("fatal_error_handler");
set_error_handler("handle_error");

//causes a warning
preg_replace();

//would normally cause a fatal error, but instead our output handler will be called allowing us to handle the error.
somefunction();
ob_end_flush();

The trick is to buffer the output and setup your error handling  and output handling first thing. When a fatal error occurs, the output from php will be sent to the function fatal_error_handler giving you one last chance to handle it.
simon dot sattes at headwork dot de
13-Jun-2003 06:06
There's a very good tutorial for PHP's error-handling available at

http://www.devshed.com/Server_Side/PHP/ErrorHandling/
Thomas Staunton
25-Mar-2003 08:11
The best way, I have found to use a class/object as an error handler is to define a class, add your desired error handling function into the constructor and then call set_error_handler() to the name of your function, thats it. e.g.

Class Error {

  Function Error() {
   Function HandleError($n, $m, $f, $l){
     print_r(debug_backtrace());
   }
   set_error_handler('HandleError');
  }
}
bob at db dot org
12-Mar-2003 05:09
The documentation on this page kindly offers the following on using (class) methods as error handlers:

Note:  Instead of a function name, an array containing an object reference and a method name can also be supplied. (Since PHP 4.3.0)

Since that's all it says about the subject, I thought I'd offer a sample implementation to show how this can be used:

<?php

      
class error {

               var
$conf;
               var
$lang;

               function
error($conf, $lang) {
                      
$this->conf = $conf;
                      
$this->lang = $lang;

                      
set_error_handler(array(&$this, 'handler'));
               }

               function
handler($no, $str, $file, $line, $ctx) {
                       echo
'<pre>';
                       echo
'no  : ' . $no . "\n";
                       echo
'str  : ' . $str . "\n";
                       echo
'file : ' . $file . "\n";
                       echo
'line : ' . $line . "\n";
                       echo
'ctx  : ';
                      
print_r($ctx);
                       echo
'</pre>';
               }

       }
?>
mmtache at yahoo dot com
10-Feb-2003 05:06
The @ operator sets the error_reporting() value to 0.
This means you can use it with your own Error Handler too. for example:

function userErrorHandler($errno, $errmsg, $filename, $linenum, $vars) {
   if (error_reporting())
echo $errmsg;
   }
set_error_handler("userErrorHandler");

function test(){
trigger_error("Error Message", E_USER_WARNING);
}

@test(); // doesn't output anything
roy
13-Jun-2002 07:08
Useful thing to note - if your error handler throws an error in itself, PHP is smart enough to use the deault error handler to handle it. This way, you don't end up in infinite flaming loops of death. This seems to be true, at least, in PHP 4.2.

('Course, there are ways to create your handler to handle even this situation, but it's probably best left this way for general purposes.)
publicmail at macfreek dot nl
01-Jun-2002 12:34
Note: If you have a custom error handler and use assert(), you MUST set:

assert_options (ASSERT_WARNING, 0);

Otherwise, no output whatsoever will ever be shown if an assert fails.
ned at wgtech dot com
02-Mar-2002 03:52
Just spent two days trying to find some method where a class can handle errors thrown at my convienience. After fighting with the pitfalls of this problem this is what I came up with. Hope it helps someone else save a little time. Its nice because all instances of this class will point to the same array that stores the errors.

class ApplicationObject {
   var $error_List;
  
   function ApplicationObject() {
       set_error_handler('trapError');
       $this->error_List = &trapError();
   }

}

function &trapError() {
   static $error_Vals = array();

   if (func_num_args()==5) { // Error Event has been passed
       $error_Vals[] = array(    'err_no' => func_get_arg(0), 'err_text' => func_get_arg(1), 'err_file' => func_get_arg(2), 'err_line' => func_get_arg(3), 'err_vars'=>func_get_arg(4));
   }
   if (func_num_args()==0) { // Setup call. Return reference
       return $error_Vals;
   }
}
j dot schriver at vindiou dot com
28-Sep-2000 11:50
A quote from Zeev Suraski:

"The CVS version (scheduled for 4.0.2) of the function has been enhanced:

- The error handler accepts three additional arguments - the filename in  which the error occured, the line number in which the error occured, and the context of the in which the error occured (a hash that points to the active symbol table at the place of the error)."

So, you can now do this:

function myErrorHandler ($errno, $errstr, $errfile, $errline, $errcontext) {...}

[Editor's Note:
The above phrase: "...the context of the in which the error occured (a hash that points to the active symbol table at the place of the error)." may be difficult for new programmers to understand.

What it means is that the last argument passed to your error handler (the $errcontext in the above example) will contain an array that contains the value of every variable that existed in the scope the error was triggered in.

Try the following example to see exactly how this works:

<pre>
<?php
// Define a simple error handler
function error_handler ($level, $message, $file, $line, $context) {

   echo <<<_END_
An error of level $level was generated in file $file on line $line.
The error message was: $message
The following variables were set in the scope that the error occurred in:

<blockquote>
_END_;

  
print_r ($context);
   print
"\n</blockquote>";
}

// Set the error handler to the error_handler() function
set_error_handler ('error_handler');

// Make a function and trigger an error
function foo () {
   global
$SERVER_ADMIN;
  
$bar = 1;

  
// Trigger the error in the local scope of the function   
  
trigger_error ("Some error");
}

foo();

// Now trigger the error in global scope
trigger_error ("Some other error");
?>

-zak@php.net]