• Non ci sono risultati.

Error Handling

Nel documento PHP Manual (pagine 187-200)

$this

Chapter 15. Error Handling

Chapter 15. Error Handling

There are several types of errors and warnings in PHP. They are:

Table 15-1. PHP error types

Value Constant Description Note

1 E_ERROR fatal run-time errors

2 E_WARNING run-time warnings (non fatal

errors)

4 E_PARSE compile-time parse errors

8 E_NOTICE run-time notices (less serious

than warnings)

16 E_CORE_ERROR fatal errors that occur during

PHP’s initial startup

PHP 4 only

32 E_CORE_WARNING warnings (non fatal errors)

that occur during PHP’s initial startup

PHP 4 only

64 E_COMPILE_ERROR fatal compile-time errors PHP 4 only

128 E_COMPILE_WARNING compile-time warnings (non

fatal errors)

PHP 4 only

256 E_USER_ERROR user-generated error message PHP 4 only

512 E_USER_WARNING user-generated warning

message

PHP 4 only

1024 E_USER_NOTICE user-generated notice

message

PHP 4 only

E_ALL all of the above, as supported

The above values (either numerical or symbolic) are used to build up a bitmask that specifies which errors to report. You can use thebitwise operatorsto combine these values or mask out certain types of errors. Note that only ’|’, ’~’, ’!’, and

’&’ will be understood withinphp.ini, however, and that no bitwise operators will be understood withinphp3.ini. In PHP 4, the defaulterror_reportingsetting isE_ALL & ~E_NOTICE, meaning to display all errors and warnings which are not E_NOTICE-level. In PHP 3, the default setting is(E_ERROR | E_WARNING | E_PARSE), meaning the same thing. Note, however, that since constants are not supported in PHP 3’sphp3.ini, theerror_reportingsetting there must be numeric; hence, it is7.

The initial setting can be changed in the ini file with theerror_reportingdirective, in your Apachehttpd.conffile 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 error_reporting() function.

Warning

When upgrading code or servers from PHP 3 to PHP 4 you should check these settings and calls to error_reporting() 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.

AllPHP expressionscan also be called with the "@" prefix, which turns off error reporting for that particular expression. If an error occurred during such an expression and thetrack_errorsfeature is enabled, you can find the error message in the global variable$php_errormsg.

Note: The@ error-control operatorprefix will not disable messages that are the result of parse errors.

Chapter 15. Error Handling

Warning

Currently the@ error-control operatorprefix will even disable error reporting for critical errors that will terminate script execution. Among other things, this means that if you use@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.

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 15-1. Using error handling in a script

<?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";

?>

This is just a simple example showing how to use theError Handling and Logging functions.

See also error_reporting(), error_log(), set_error_handler(), restore_error_handler(), trigger_error(), user_error()

Chapter 15. Error Handling

Chapter 16. Creating and manipulating images

PHP is not limited to creating just HTML output. It can also be used to create and manipulate image files in a variety of different image formats, including gif, png, jpg, wbmp, and xpm. Even more convenient, php can output image streams directly to a browser. You will need to compile PHP with the GD library of image functions for this to work. GD and PHP may also require other libraries, depending on which image formats you want to work with. GD stopped supporting Gif images in version 1.6.

Example 16-1. PNG creation with PHP

<?php

Header("Content-type: image/png");

$string=implode($argv," ");

$im = imageCreateFromPng("images/button1.png");

$orange = ImageColorAllocate($im, 220, 210, 60);

$px = (imagesx($im)-7.5*strlen($string))/2;

ImageString($im,3,$px,9,$string,$orange);

ImagePng($im);

ImageDestroy($im);

?>

This example would be called from a page with a tag like: <img src="button.php?text"> The above button.php script then takes this "text" string an overlays it on top of a base image which in this case is "images/button1.png" and outputs the resulting image. This is a very convenient way to avoid having to draw new button images every time you want to change the text of a button. With this method they are dynamically generated.

Chapter 16. Creating and manipulating images

Chapter 17. HTTP authentication with PHP

The HTTP Authentication hooks in PHP are only available when it is running as an Apache module and is hence not available in the CGI version. In an Apache module PHP script, it is possible to use the Header() function to send an

"Authentication Required" message to the client browser causing it to pop up a Username/Password input window. Once the user has filled in a username and a password, the URL containing the PHP script will be called again with the variables,

$PHP_AUTH_USER, $PHP_AUTH_PW and $PHP_AUTH_TYPE set to the user name, password and authentication type respectively. Only "Basic" authentication is supported at this point. See the Header() function for more information.

An example script fragment which would force client authentication on a page would be the following:

Example 17-1. HTTP Authentication example

<?php

if(!isset($PHP_AUTH_USER)) {

Header("WWW-Authenticate: Basic realm=\"My Realm\"");

Header("HTTP/1.0 401 Unauthorized");

echo "Text to send if user hits Cancel button\n";

exit;

} else {

echo "Hello $PHP_AUTH_USER.<P>";

echo "You entered $PHP_AUTH_PW as your password.<P>";

}

?>

Instead of simply printing out the $PHP_AUTH_USER and $PHP_AUTH_PW, you would probably want to check the username and password for validity. Perhaps by sending a query to a database, or by looking up the user in a dbm file.

Watch out for buggy Internet Explorer browsers out there. They seem very picky about the order of the headers. Sending the WWW-Authenticate header before the HTTP/1.0 401 header seems to do the trick for now.

In order to prevent someone from writing a script which reveals the password for a page that was authenticated through a traditional external mechanism, the PHP_AUTH variables will not be set if external authentication is enabled for that particular page. In this case, the $REMOTE_USER variable can be used to identify the externally-authenticated user.

Note, however, that the above does not prevent someone who controls a non-authenticated URL from stealing passwords from authenticated URLs on the same server.

Both Netscape Navigator and Internet Explorer will clear the local browser window’s authentication cache for the realm upon receiving a server response of 401. This can effectively "log out" a user, forcing them to re-enter their username and password. Some people use this to "time out" logins, or provide a "log-out" button.

Example 17-2. HTTP Authentication example forcing a new name/password

<?php

function authenticate() {

Header( "WWW-authenticate: basic realm=\"Test Authentication System\"");

Header( "HTTP/1.0 401 Unauthorized");

echo "You must enter a valid login ID and password to ac-cess this resource\n";

exit;

}

if(!isset($PHP_AUTH_USER) || ($SeenBefore == 1 && !str-cmp($OldAuth, $PHP_AUTH_USER)) ) {

authenticate();

} else {

echo "Welcome: $PHP_AUTH_USER<BR>";

echo "Old: $OldAuth";

echo "<FORM ACTION=\"$PHP_SELF\" METHOD=POST>\n";

echo "<INPUT TYPE=HIDDEN NAME=\"SeenBefore\" VALUE=\"1\">\n";

Nel documento PHP Manual (pagine 187-200)

Documenti correlati