Adjusting PHP Error Settings to Assist Debugging

Error Reporting Levels

In PHP 5, the default reporting level is E_ALL & ~E_NOTICE. While it is nice to hide the 'Notice' messages, it is better to set the error reporting level to E_ALL. In fact, since PHP 5.3, using E_ALL ^ E_STRICT provides even more detailed messages. Notice and strict messages tell you useful things like if a variable has not been initiated or a function is deprecated.

If notice and strict messages are hard to get rid of, this can indicate underlying issues with the program logic. For example if you had the code:

$GLOBALS["foo"]["path"]["relative"]["bar"]["images"] = 'something'; ... Notice: Undefined index: foo

A natural question arises: 'why are you using a five dimensional array?'. Could you organize your data structures better? (this is just an example)

As developers we should strive to have high quality code and use all the tools we are provided with - one of them being error reporting.

for more on error_reporting function

//instead of error_reporting(E_ALL & ~E_NOTICE); //use error_reporting(E_STRICT);

Of course, when your code is in a production environment, you will want to make sure to log messages instead of displaying them:

ini_set('display_errors', '0'); ini_set('log_errors', '1');

The most common reason for E_NOTICE messages are not initiating ensuring that a variable is set before trying to check its value.

1)  Initiate all variables. In the following code:

function a($b){ if($b){ $html .= 'something'; }else{ $html .= 'something else'; } return $html; }

We are trying to concatenate to the $html variable which has not been defined in the function scope. Since it is also not defined in the global scope, executing the code, will produce the message:

Notice: Undefined variable: html ...

Initiating the variable eliminates the warning.

function a($b){ $html = ''; if($b){ $html .= 'something'; }else{ $html .= 'something else'; } return $html; }

This is a practice to get into, for security and other reasons.

2) If you receive notices on a class property not being defined, then you should define it!

if($this->some_attribute){;} Notice: Undefined Property: ... class foobar{ private $some_attribute; }

For the superglobal variables $_GET, $_POST, $_SESSION and $_COOKIE check an index is set before trying to use its value. Instead of

if ($_GET['id']) {

Check for existence. You may also want to handle the case where isset returns false separately. Perhaps the variable is critical and you want to alert the user that an error occurred.

if (isset($_GET['id'] && $_GET['id']) {

3) Use quotes on word array indices. PHP is usually smart enough to guess that this is what is meant, but sometimes gets tripped up.

//bad echo $animal[dog]; //good echo $animal['dog'];

Debugging

Debugging in PHP can be difficult.Types are loose and so are programming standards.

To combat this, you can:

  • install/enable xdebug. (Worthwhile for readable var_dump and print_r statements alone)
  • use try/catch blocks
  • do not use the error suppression operator, @ (more on this below)

You should never (ok rarely) use the error suppression operator, @ . It can produce a lot of frustration when you try to debug code later and get a white page which has silently died, providing no useful diagnostic error messages

The php.net page, http://php.net/manual/en/language.operators.errorcontrol.php, even warns about this: "Warning Currently the "@" error-control operator prefix 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. "

Add new comment