<chapter id="features.error-handling"> <title>Error Handling</title> <para> There are several types of errors and warnings in PHP. They are: <table> <title>PHP error types</title> <tgroup cols="4"> <thead> <row> <entry>Value</entry> <entry>Constant</entry> <entry>Description</entry> <entry>Note</entry> </row> </thead> <tbody> <row> <entry>1</entry> <entry>E_ERROR</entry> <entry>fatal run-time errors</entry> <entry></entry> </row> <row> <entry>2</entry> <entry>E_WARNING</entry> <entry>run-time warnings (non fatal errors)</entry> <entry></entry> </row> <row> <entry>4</entry> <entry>E_PARSE</entry> <entry>compile-time parse errors</entry> <entry></entry> </row> <row> <entry>8</entry> <entry>E_NOTICE </entry> <entry> run-time notices (less serious than warnings) </entry> <entry></entry> </row> <row> <entry>16</entry> <entry>E_CORE_ERROR</entry> <entry>fatal errors that occur during PHP's initial startup</entry> <entry>PHP 4 only</entry> </row> <row> <entry>32</entry> <entry>E_CORE_WARNING</entry> <entry> warnings (non fatal errors) that occur during PHP's initial startup </entry> <entry>PHP 4 only</entry> </row> <row> <entry>64</entry> <entry>E_COMPILE_ERROR</entry> <entry>fatal compile-time errors</entry> <entry>PHP 4 only</entry> </row> <row> <entry>128</entry> <entry>E_COMPILE_WARNING</entry> <entry>compile-time warnings (non fatal errors)</entry> <entry>PHP 4 only</entry> </row> <row> <entry>256</entry> <entry>E_USER_ERROR</entry> <entry>user-generated error message</entry> <entry>PHP 4 only</entry> </row> <row> <entry>512</entry> <entry>E_USER_WARNING</entry> <entry>user-generated warning message</entry> <entry>PHP 4 only</entry> </row> <row> <entry>1024</entry> <entry>E_USER_NOTICE </entry> <entry>user-generated notice message</entry> <entry>PHP 4 only</entry> </row> <row> <entry></entry> <entry>E_ALL</entry> <entry>all of the above, as supported</entry> <entry></entry> </row> </tbody> </tgroup> </table> </para> <para> The above values (either numerical or symbolic) are used to build up a bitmask that specifies which errors to report. You can use the <link linkend="language.operators.bitwise">bitwise operators</link> to combine these values or mask out certain types of errors. Note that only '|', '~', '!', and '&' will be understood within <filename>php.ini</filename>, however, and that no bitwise operators will be understood within <filename>php3.ini</filename>. </para> <para> In PHP 4, the default <link linkend="ini.error-reporting">error_reporting</link> setting is <literal>E_ALL & ~E_NOTICE</literal>, meaning to display all errors and warnings which are not E_NOTICE-level. In PHP 3, the default setting is <literal>(E_ERROR | E_WARNING | E_PARSE)</literal>, meaning the same thing. Note, however, that since constants are not supported in PHP 3's <filename>php3.ini</filename>, the <link linkend="ini.error-reporting">error_reporting</link> setting there must be numeric; hence, it is <literal>7</literal>. </para> <para> The initial setting can be changed in the ini file with the <link linkend="ini.error-reporting">error_reporting</link> directive, in your Apache <filename>httpd.conf</filename> file with the php_error_reporting (php3_error_reporting for PHP 3) directive, and lastly it may be set at runtime within a script by using the <function>error_reporting</function> function. </para> <warning> <para> When upgrading code or servers from PHP 3 to PHP 4 you should check these settings and calls to <function>error_reporting</function> or you might disable reporting the new error types, especially E_COMPILE_ERROR. This may lead to empty documents without any feedback of what happened or where to look for the problem. </para> </warning> <para> All <link linkend="language.expressions">PHP expressions</link> can also be called with the "@" prefix, which turns off error reporting for that particular expression. If an error occurred during such an expression and the <link linkend="ini.track-errors">track_errors</link> feature is enabled, you can find the error message in the global variable <literal>$php_errormsg</literal>. </para> <note> <para> The <link linkend="language.operators.errorcontrol">@ error-control operator</link> prefix will not disable messages that are the result of parse errors. </para> </note> <warning> <para> Currently the <link linkend="language.operators.errorcontrol">@ error-control operator</link> prefix will even disable error reporting for critical errors that will terminate script execution. Among other things, this means that if you use <link linkend="language.operators.errorcontrol">@</link> to suppress errors from a certain function and either it isn't available or has been mistyped, the script will die right there with no indication as to why. </para> </warning> <para> Below we can see an example of using the error handling capabilities in PHP. We define a error handling function which logs the information into a file (using an XML format), and e-mails the developer in case a critical error in the logic happens. <example> <title>Using error handling in a script</title> <programlisting role="php"> <?php // we will do our own error handling error_reporting(0); // user defined error handling function function userErrorHandler ($errno, $errmsg, $filename, $linenum, $vars) { // timestamp for the error entry $dt = date("Y-m-d H:i:s (T)"); // define an assoc array of error string // in reality the only entries we should // consider are 2,8,256,512 and 1024 $errortype = array ( 1 => "Error", 2 => "Warning", 4 => "Parsing Error", 8 => "Notice", 16 => "Core Error", 32 => "Core Warning", 64 => "Compile Error", 128 => "Compile Warning", 256 => "User Error", 512 => "User Warning", 1024=> "User Notice" ); // set of errors for which a var trace will be saved $user_errors = array(E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE); $err = "<errorentry>\n"; $err .= "\t<datetime>".$dt."</datetime>\n"; $err .= "\t<errornum>".$errno."</errnumber>\n"; $err .= "\t<errortype>".$errortype[$errno]."</errortype>\n"; $err .= "\t<errormsg>".$errmsg."</errormsg>\n"; $err .= "\t<scriptname>".$filename."</scriptname>\n"; $err .= "\t<scriptlinenum>".$linenum."</scriptlinenum>\n"; if (in_array($errno, $user_errors)) $err .= "\t<vartrace>".wddx_serialize_value($vars,"Variables")."</vartrace>\n"; $err .= "</errorentry>\n\n"; // for testing // echo $err; // save to the error log, and e-mail me if there is a critical user error error_log($err, 3, "/usr/local/php4/error.log"); if ($errno == E_USER_ERROR) mail("phpdev@mydomain.com","Critical User Error",$err); } function distance ($vect1, $vect2) { if (!is_array($vect1) || !is_array($vect2)) { trigger_error("Incorrect parameters, arrays expected", E_USER_ERROR); return NULL; } if (count($vect1) != count($vect2)) { trigger_error("Vectors need to be of the same size", E_USER_ERROR); return NULL; } for ($i=0; $i<count($vect1); $i++) { $c1 = $vect1[$i]; $c2 = $vect2[$i]; $d = 0.0; if (!is_numeric($c1)) { trigger_error("Coordinate $i in vector 1 is not a number, using zero", E_USER_WARNING); $c1 = 0.0; } if (!is_numeric($c2)) { trigger_error("Coordinate $i in vector 2 is not a number, using zero", E_USER_WARNING); $c2 = 0.0; } $d += $c2*$c2 - $c1*$c1; } return sqrt($d); } $old_error_handler = set_error_handler("userErrorHandler"); // undefined constant, generates a warning $t = I_AM_NOT_DEFINED; // define some "vectors" $a = array(2,3,"foo"); $b = array(5.5, 4.3, -1.6); $c = array (1,-3); // generate a user error $t1 = distance($c,$b)."\n"; // generate another user error $t2 = distance($b,"i am not an array")."\n"; // generate a warning $t3 = distance($a,$b)."\n"; ?> </programlisting> </example> This is just a simple example showing how to use the <link linkend="ref.errorfunc">Error Handling and Logging functions</link>. </para> <para> See also <function>error_reporting</function>, <function>error_log</function>, <function>set_error_handler</function>, <function>restore_error_handler</function>, <function>trigger_error</function>, <function>user_error</function> </para> </chapter> <!-- Keep this comment at the end of the file Local variables: mode: sgml sgml-omittag:t sgml-shorttag:t sgml-minimize-attributes:nil sgml-always-quote-attributes:t sgml-indent-step:1 sgml-indent-data:t sgml-parent-document:nil sgml-default-dtd-file:"../../manual.ced" sgml-exposed-tags:nil sgml-local-catalogs:nil sgml-local-ecat-files:nil End: -->