Programming Errors

Chapter 11 - Debugging Your Code
byGareth Downes-Powellet al.
Wrox Press 2003

Understanding the various error types and error messages is essential to debugging your PHP code. In this section we are going to look at the various types of errors that can occur.

The first types of errors we are going to look at are programming errors. These can be broken down into three main categories, and we'll look at each of these separately, and how to avoid them.

  • Syntax errors

  • Run-time errors

  • Logic errors

Syntax Errors

Syntax errors are caused by an error in your code, and are probably one of the commonest errors you'll see. Common examples of syntax errors are misspelling a function, missing a semicolon from the end of a statement, or missing a closing bracket.

As an example, if we try and open a web page with the following code:

    6   <?php    7     echo("Debugging your Code")    8     echo("Part 1");    9   ?> 

We will get an error message similar to the following:

Parse error: parse error, expecting ''," or '';" in /home/sites/site17/web/errors/error1.php on line 8

We can see that the error isn't actually on line 8; it's because of the missing semicolon at the end of line 7.

When you get an error message similar to the one above, it's always worth looking backwards through the code a couple of lines, as often an error lies there, instead of on the line shown by the error message. This occurs because the PHP parser recognizes that a semicolon is missing, but keeps parsing to the end of the code block trying to find it. As a result when the PHP parser has got to the last line of the code block, and has still not found the missing semicolon, it shows the error message, but the line number shown is the line the PHP parser is currently on, which is the last line of the code block.

If you haven't already, it's a good idea to turn on the Line Numbers option for Code view or the Code inspector, which you can do by clicking the View Options button, which is on the Dreamweaver MX Document toolbar.

If you haven't got the Document toolbar turned on, then select View -> Toolbars -> Document. You can see the Document toolbar, and the View Options button in the screenshot opposite.

click to expand

You now have the line numbers printed alongside the code, and it makes it much easier to track down the line the error applies to.

Another syntax error which is common, but can be harder to track, is a missing } (a curly brace) at the end of a code block. If we take a look at the code below:

    1   <html>    2    <head>    3      <title>Untitled Document</title>    4      <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">    5    </head>    6    <?php    7      if($Submit == "Submit") {    8        echo("Debugging your Code");    9        echo("Part 1");    10   ?>    11   <body>    12   </body>    13   </html> 

When this page is viewed in a browser, it can lead to an error message similar to the following:

Parse error: parse error in/home/sites/site17/web/errors/error1.php on line 13

We can see straight away that the problem is actually caused by a missing }, which should be at the end of line 9. So why does the missing bracket on line 9 give a parse error on line 13? Again, the reason behind this is because PHP knows that a closing bracket should be there, and so it checks all the way to the end of the code trying to find it. When it reaches the end of the code (line 13 in our example), it shows the error message, giving the last line as the line with the error in the error report. These errors can be tricky to find, as the line number in the error message no longer corresponds to the actual line giving the error.

In cases like this you need to manually work through the code, and check that for each { there is a closing }. This is made a lot easier if you have indented your code, as it's easier to see the program flow, and where code blocks start and end.

The Balance Braces function in Dreamweaver MX also makes this process much easier. We covered the Balance Braces in detail in Chapter 9 on Hand Coding, but to recap you can place the cursor in a block of code and select Edit > Balance Braces, or use the key combination Ctrl + '. If the braces are balanced, that is there is an opening and closing brace ( { } ), the code block will be highlighted, showing you that code block is correct, and the braces are balanced. By starting on the innermost block of code, you can work your way outwards, checking the braces are balanced, which significantly cuts down the time taken to find and correct the source of the error.

Another common cause of errors when writing PHP is variable type. PHP is known as a loosely typed language, as variables can change from one type to another during run-time. This means that you can for example place a string in a variable, which previously held a numerical value. Although this is convenient, it means that you can have a situation where you assume one type of data is in a variable, whereas it's actually a different type altogether.

Another easy mistake to make is forgetting the case of a variable name, for example, $myvariable is a totally separate variable to $myVariable. This can cause you problems if you're working on a lot of code, and you switch from one to the other.

It helps if you set yourself a standard naming convention when working on a site, so that everybody names their variables using the same guidelines, and so avoids errors when the code is run. For example, if you have a variable name consisting of two words for example $showtotal, it is easier to understand if you capitalize the first letter of the second word, for example $showTotal. This way you can clearly see where one word ends and the next word starts.

Run-time Errors

Run-time errors occur when the program is actually running, and can be caused by outside events, rather than errors in your code. For example, your code could work fine for months, but as soon as the server's hard disk becomes full, it crashes when it tries to output a file. Another example is when you're pulling data from another site. Although your code works the way it was intended, the other site's server could be down, causing your code to crash if there is no error checking. Perhaps your site uses an include file. If that include file is deleted, any code calling a function in that file will return an error when the script tries to load it.

Scenarios like these should be thought of in advance. You need to add relevant error trapping to your code, so that if a problem does arise, your web site returns a professional and easy-to-understand message telling the user what's gone wrong, rather than stopping in the middle of a page and displaying a standard error message.

Another example of run-time errors occurring is when a user enters text into a box meant for a numerical value. It's amazing what people will enter into your forms either accidentally, or even maliciously, trying to crash your code and / or reveal internal data. On an e-commerce site, for example, what would your script do it the user entered a negative rather than a positive quantity for an item in their cart, would it end up refunding the card instead of charging it?

Don't leave anything to chance, and always check the user input is valid, and is the same type of data that you are expecting. Set up form fields with a character maximum the same as the character maximum of the field in the database you're inserting them into.

We'll be talking about ways of trapping and dealing with run-time errors later in this chapter, so that the page carries on functioning and displays a friendly error message, rather than just crashing.

Logic Errors

Logic errors occur when your code is technically correct, but doesn't do what you intended it to do. If you look at the following piece of code:

    1   <html>    2     <head>    3     <title>Untitled Document</title>    4     <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">    5     </head>    6      <body>    7      <table width="50%" height="8" border="1" align="center"           cellpadding="0" cellspacing="0">    8            <tr align="center">    9            <?php    10             for($myCount=0; $myCount < 5; $myCount++);    11               echo("<td>" . $myCount . "</td>");    12           ?>    13           </tr>    14   </table>    15    </body>    16   </html> 

When we run this code, we would expect the output to be:

click to expand

Instead the page appears as follows:

click to expand

Why is this happening? If you look at lines 10 and 11 which read:

   10          for($myCount=0; $myCount < 5; $myCount++);   11            echo("<td>" . $myCount . "</td>"); 

You can see that at the end of line 10 there is a semicolon added by mistake. This means that the loop runs as it should, but because of the extra semicolon, line 11 is only executed when the count is completed, rather than for each stage of the count.

Notice that the code still executes and runs without any error messages, as the code is perfectly valid, even though it didn't do what we wanted it to do. As a result of this, these errors can sometimes be hard to track down.

This is much less likely to occur if you use braces ( {} ) for all loops, for example for the lines with the error above, it would be better if they had been written as:

    10          for($myCount=0; $myCount < 5; $myCount++){    11            echo("<td>" . $myCount . "</td>");} 

Error Types in PHP

As we've seen in the previous section, PHP error messages usually give an adequate description of the error that's occurred, along with the line number of the code with the error. For example:

Parse error: parse error in /home/sites/site17/web/errors/error1.php on line 15

Usually though, this isn't an error that you would want the users of your site to see, as it looks unprofessional, and can make your users lose trust in the site, which could be extremely damaging, for example to an e-commerce web site. PHP comes to the rescue however, and allows you to write your own custom error-handling functions, which can output HTML and show a more user-friendly error message. PHP also provides three custom error types that you can use to handle errors in your code.

We're now going to take a look at the different error types that are available within PHP.

Standard Error Types

There are twelve standard error types, which are shown in the table below. Some errors are warnings, and allow the script to continue running, others require the script to halt.

Constant

Description

Notes

E_ERROR

fatal run-time errors

 

E_WARNING

run-time warnings (non fatal-errors)

 

E_PARSE

compile-time parse errors

 

E_NOTICE

run-time notices (less serious than warnings)

 

E_CORE_ERROR

fatal errors that occur during PHP's initial startup

PHP 4 only

E_CORE_WARNING

warnings( non fatal errors) that occur during PHP's initial startup

PHP 4 only

E_COMPILE_ERROR

fatal compile-time errors

PHP 4 only

E_COMPILE_WARNING

compile-time warnings (non-fatal errors)

PHP 4 only

E_USER_ERROR

user-generated error message

PHP 4 only

E_USER_WARNING

user-generated warning message

PHP 4 only

E_USER_NOTICE

user-generated notice message

PHP 4 only

E_ALL

all of the above

 

PHP Standard Error Types

We're now going to look at each of the above error types separately (apart from E_USER error types, which we'll be looking at later in this chapter, as these allow you to enter your own error messages unlike the other PHP error types).

E_ERROR -Fatal

E_ERROR is a fatal error, which means that if this error is encountered, the PHP script will halt, as the error cannot be recovered from. This error type is displayed by default.

E_WARNING -Non-Fatal

E_WARNING is an example of a non-fatal error. A non-fatal error is one that can be recovered from, and the script can continue running. It's normally caused by something that could have been prevented within the code, such as passing a parameter with the wrong data type to a function. Although this error is non-fatal, it is displayed to the user by default.

E_PARSE -Fatal

E_PARSE occurs when the PHP parser encounters an error, for example a syntax error. In PHP 4 the script is parsed before it is run, and the script will terminate then if the parsing process finds any errors.

E_NOTICE -Non-Fatal

E_NOTICE is another non-fatal error. This error isn't reported by default, because it could be generated during normal execution of a script. It's normally caused by an error in the script, such as trying to reference an undefined variable.

E_CORE_ERROR -Fatal

E_CORE_ERROR means that there is a problem with the PHP engine starting up. This is the same type of error as E_ERROR.

E_CORE_WARNING -Non Fatal

E_CORE_WARNING is similar to the E_WARNING type above. It reports non-fatal failures during the startup of the PHP Engine.

E_COMPILE_ERROR -Fatal

E_COMPILE_ERROR is generated by the PHP Engine and reports errors in compilation.

E_COMPILE_WARNING -Non-Fatal

E_COMPILE_WARNING is similar to the E_WARNING type above, but reports non-fatal errors in compilation.

The last four errors (the CORE and COMPILE type errors) will not normally be seen on a day-to-day basis, as they are more to do with the setup of the server, and are not likely to occur when an installation is stable.

Error Reporting Levels

Setting a custom Error Reporting Level, means that you can tell PHP which errors to report, and which to ignore. You can tell PHP for example to show all errors, which gives you extra information when you're writing and debugging your code, and then when the site goes live to only show the important errors, and ignore warnings for example.

The default error reporting level is set with the error_reporting option in your php.ini file. If you do not have access to the php.ini file, because you are on shared hosting for example, you can set the error reporting level on a per script basis, using the error_reporting() function.

The error types can be referred to symbolically (by using the constant in the table above), or numerically (by using the error value in the table above). You can select which error types are shown, by using a combination of the error types, and the operators shown below:

Name

Operator

Example

AND

&

E_ERROR & E_WARNING

OR

|

E_ERROR | E_CORE_ERROR

NOT

~

~ E_NOTICE

Error Type Operators

By combining the error values or constants with the operators above, you can create a custom level of error reporting.

In PHP 4, the default error reporting setting is:

    E_ALL & -E_NOTICE 

This can be read as:

    E_ALL And Not E_NOTICE 

This means that PHP will display all errors and warnings, except those of type E_NOTICE.

By combining the operators in the table above, and the Error Types in the table earlier in the chapter, you can create different combinations of errors and warnings etc. that are reported. For example to only show fatal error messages, and to ignore all warnings and notices, you could use the combination:

    E_ERROR & E_CORE_ERROR & E_COMPILE_ERROR & E_PARSE 

This enables you to easily create a custom level, showing only the information you require.

Changing the Error Reporting Settings

We're now going to discuss changing the error reporting settings to our own custom level, using the information above.

We could then turn on error reporting for all the different error types and warnings, so we can get as much information as possible when code is being tested and debugged. For example, if you take a look at the code below:

    <?php      for($myCount=0; $myCount<10; $mycount++){        echo "$myCount";      }    ?> 

If you run the above code in a browser (not advisablel), all you would get is a never-ending stream of 0's sent to the browser. Because $mycount is never incremented, due to it being mis-typed (it is typed as $mycount++), the code goes into an endless loop. Because the code is valid however, with the default level of error reporting, the code is executed, and an endless loop occurs.

If however you set the error reporting level to report everything, using the setting E_ALL as in the following code example:

    <?php       error_reporting(E_ALL);      for($myCount=0; $myCount<10; $mycount++){        echo "$myCount";      }    ?> 

This would cause an error to be triggered, and PHP would show the following error:

 Warning: Undefined variable: mycount in /home/sites/site17/users/phpbook/web/errors/test2.php on line 9 

You could then intercept this error, and stop the endless loop from occurring.

When your site goes live, you can set the error reporting back to the default level, or choose a custom level of your own, as all the minor errors will have been fixed, and you would not want notices etc. to be shown.

There are two ways of changing the error reporting level, on a global level, or on a per-script basis, and we are going to look at both of these.

Setting the Error Level Globally

If you want to change the error level globally, so it affects all scripts running on that server, you need to edit your php.ini file.

If you are not sure of the location of your php.ini file, you can use the incredibly useful phpinfo() function. We'll look at this in more detail later on, for the time being add the following PHP code to a blank page, upload it to your server, and then view it in your browser.

    <?php        phpinfo();    ?> 

At the very top of the information, in the first table, the path to your php.ini is displayed.

Edit your php.ini file, and under the heading

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;    ; Error handling and logging ;    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 

you will find the following four directives.

    error reporting = E_ALL & ~E_NOTICE    display_errors = On    log_errors = Off    track_errors = Off 

The above shows the default settings for a PHP installation.

The meanings of these directives are as follows:

    error_reporting = E_ALL & ~E_NOTICE 

This directive allows you to set a custom level of error reporting, as we discussed above, and holds the error types and operators that define your custom error level.

    display_errors = Off | On 

This directive specifies whether error messages should be printed as HTML output or not

    log_errors = Off | On 

This directive controls whether error messages are logged to the server error logs or not..

    track_errors = Off | On 

If this directive is set to On, the last error message will be stored in the PHP global variable $php_errormsg.

When you have saved the changes, you will need to restart your web server, so that the changes can take effect.

Changing the Error Level On a Per-Script Basis

If you don't have access to the php.ini file, or don't want to make global changes, you can set the error reporting level on a per-script basis with the error_reporting() function. The format for the error_reporting() function is:

    error_reporting(level) 

When you call the error_reporting() function to set a new level of error reporting, the previous error reporting level is returned. To set the error reporting level you enter a combination of the error types as shown in the previous tables. So if we wanted to set the PHP default of E_ALL & ~E_NOTICE, which means ALL_ERRORS apart from E_NOTICE, we would use:

    E_ALL - E_NOTICE 

So the following piece of code:

    <?php        $oldSetting = error_reporting(E_ALL - E_NOTICE);    ?> 

would set the error reporting level to the default level, and the previous level would be stored in $oldSetting. If desired you can restore back to the old setting later in your script using the code:

    <?php           error_reporting($oldSetting);    ?> 

To turn on all error reporting and notices use:

    <?php        $oldSetting = error_reporting(E_ALL);    ?> 

Being able to change the error reporting level is extremely useful, as you can turn on all error reporting when you are developing and debugging, and then drop back down to the default level when your site goes live, so that extra information such as notices are not shown.

User-Defined Errors

As well as the standard error types PHP 4 also allows three custom error types. We saw these briefly earlier in the chapter, and they are reprinted below.

Value

Constant

Description

Notes

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

We're now going to look at the different user error types, and give examples of how they could be used.

E_USER_ERROR

E_USER_ERROR is the most serious of the user-defined error messages allowed by PHP. It is of the same type of error as E_ERROR, and should only be triggered when the script is going to process some code that would cause a critical error, and it requires the script to be halted.

An example of its use would be in a routine which checks parameters before a division operation occurs, and the error is triggered if a divide by zero is going to take place.

E_USER_WARNING

E_USER_WARNING is a user-defined version of the E_WARNING error type, and is used for errors that prevent the script from running as normal.

An example of its use would be in a routine to check the data being sent to a function is the correct type. If a function was expecting an array as one of its parameters and it was passed a string, the error should be triggered, as PHP can't convert a string to an array.

E_USER_NOTICE

E_USER_NOTICE is, as you would expect, of the same type as its E_NOTICE counterpart. Its use is for displaying potential warning messages, which are non-fatal and won't stop the execution of the script.

Now we've looked at the user-defined error types, in the next section we show how to use them in your script.

Custom Error Handling

Custom error handling gives you much more control over the message the user sees should anything happen to go wrong. It looks much more professional to show a customized error message, with your header and footer etc., rather than the standard PHP error message.

Triggering an Error

Using the trigger_error() function, you can trigger your own error message or warning, which is either dealt with by the internal PHP error handler, or with your own custom error handler.

For example, the following code:

    <?php        trigger_error("This creates a Fatal Error!", E_USER_ERROR);    ?> 

would trigger a fatal error when it was run, halting the execution of the script, and showing the error message:

Fatal error: This creates a Fatal Error!

The format for the trigger_error() function is:

 trigger_error (error_msg [,error_type]) 

trigger_error() is called with a string containing the error message, and optionally, E_USER_NOTICE, E_USER_WARNING, or E_USER_ERROR.

If the error type is not supplied, the error is shown as the default error type E_USER_NOTICE.

The following code shows the results of all 3 error types:

    7 <?php    8   trigger_error("Test error message", E_USER_NOTICE);    9    10  echo "Recovered from E_USER_NOTICE error type";    11    12  trigger_error("Test error message", E_USER_WARNING);    13    14  echo "Recovered from E_USER_WARNING error type";    15    16  trigger_error("Test error message", E_USER_ERROR);    17    18  echo "Recovered from E_USER_ERROR error type";    19 ?> 

Here's what the user would see:

click to expand

Note that the first two error types E_USER_NOTICE and E_USER_WARNING, do not stop the execution of the code, and it continues running. E_USER_ERROR however, shows the "Fatal error" message, and the script is halted, and the text on line 18 is never displayed.

Another function you can use to trigger user errors is user_error(), which is an alias of the trigger_error() function above, and either function can be used.

Handling Errors When They Occur

Now we've looked at the different error types, and how to trigger errors, we're going to look at how to handle errors when they occur. Normally, as we've seen above, the built-in PHP error handler takes over if an error occurs.

The set_error_handler() Function

Using the set_error_handler() function, we can set our own function to handle any errors that occur.

The format for set_error_handler() is:

    set_error_handler (error_handler) 

where error_handler is the name of your function, for example:

    set_error_handler("myErrorHandler") 

Before we use set_error_handler(), we need to have a function to set as the error handler, and we'll create this function now. The custom error handler function needs to be able to accept two parameters, an error number and an error string. By comparing the error number to a list in your script, you can decide which action is necessary for that error. The error string contains the internal description of the error.

From PHP 4.0.2 another three parameters were added, for the filename where the error occurred, the line number where the error occurred, and the context in which the error occurred.

These extra parameters are:

  • $error_file - The filename of the script that triggered the error.

  • $error_line - The line number of the code that triggered the error.

  • $error_context - Contains an array of all variables that were in use at the time of the error.

As an example, look at the code below:

    <?php      function errorHandler($errNumber, $errDetails, $errFile, $errLine, $errContext){        echo "Error Number: $errNumber <br>";        echo "Error Details: $errDetails <br>";        echo "Error File: $errFile <br>";        echo "Error Line: $errLine <br><br>";        foreach($errContext as $key=>$value){          echo "Error Context: $key : $value <br>";        }      }    ?>    <html>    <head>    <title>Custom</title>    </head>    <body>    <?php      set_error_handler("errorHandler");      user_error("This is a test error", E_USER_ERROR);    ?>    </body>    </html> 

This code sets up a simple error handler that prints all the parameters that are sent to it by the PHP engine. Note that as $errContext is an array, we have to loop through it, so we can print all its data.

In the body of the code we trigger a test error, so that the errorHandler function will be invoked. When the page is viewed in a browser, the following is seen:

 Error Number: 256 Error Details: This is a test error Error File: /home/sites/site17/users/phpbook/web/errors/test2.php Error Line: 20 Error Context: DOCUMENT_ROOT : /home/sites/sitel7/web Error Context: HTTP_ACCEPT : */* Error Context: HTTP_ACCEPT_ENCODING : gzip, deflate Error Context: HTTP_ACCEPT_LANGUAGE : en-gb Error Context: HTTP_CLIENT_IP : 86.7.104.102 Error Context: HTTP_HOST : php.myserver.com Error Context: HTTP_USER_AGENT : Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; Q356871) Error Context: HTTP_VIA : HTTP/1.1 (Traffic-Server/4.2.15-M-12744 [uScM]) Error Context: PATH : /sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin Error Context: REMOTE_ADDR : 128.152.69.10 Error Context: REMOTE_PORT : 53091 Error Context: SCRIPT_FILENAME : /home/sites/site17/users/phpbook/web/errors/test2.php Error Context: SCRIPT_URI : http://php.myserver.com/~phpbook/errors/error2.php Error Context: SCRIPT_URL : /~phpbook/errors/error2.php Error Context: SERVER_ADDR : 218.64.212.84 Error Context: SERVER_ADMIN : gareth Error Context: SERVER_NAME : php.myserver.com Error Context: SERVER_PORT : 80 Error Context: SERVER_SIGNATURE : Error Context: SERVER_SOFTWARE : Apache/1.3.20 Sun Cobalt (Unix) mod_ssl/2.8.4 OpenSSL/0.9.6b PHP/4.1.2 mod_auth_pam_external/0.1 FrontPage/4.0.4.3 mod_perl/1.25 Error Context: UNIQUE_ID : PPcCsCRDwxOBNGHVRf4 Error Context: GATEWAY_INTERFACE : CGI/1.1 Error Context: SERVER_PROTOCOL : HTTP/1.1 Error Context: REQUEST_METHOD : GET Error Context: QUERY_STRING : Error Context: REQUEST_URI : /~phpbook/errors/error2.php Error Context: SCRIPT_NAME : /~phpbook/errors/error2.php Error Context: PATH_TRANSLATED : /home/sites/sitel7/users/phpbook/web/errors/error2.php Error Context: PHP_SELF : /-phpbook/errors/error.php Error Context: HTTP_POST_VARS : Array Error Context: _POST : Array Error Context: HTTP_GET_VARS : Array Error Context: _GET : Array Error Context: HTTP_COOKIE_VARS : Array Error Context: _COOKIE : Array Error Context: HTTP_SERVER_VARS : Array Error Context: _SERVER : Array Error Context: HTTP_ENV_VARS : Array Error Context: _ENV : Array Error Context: HTTP_POST_FILES : Array Error Context: _FILES : Array Error Context: _REQUEST : Array 

As you can see, the errContext array holds a huge amount of data, about the server and the different types of variables that were present at the time of the error.

Building a Custom Error Handler

Our error handler needs to be able to trap the E_ERROR and E_USER_ERROR levels of error, and instead of simply displaying the standard error message, it's going to show a more professional-looking error message, which is also more user friendly.

Here is the code for our custom error handler:

    <?php    function customErrorHandler($error_num, $error_string) {      // Check error type is either E_ERROR or E_USER_ERROR      if ($error_num == E_ERROR || $error_num == E_USER_ERROR){        echo "           <div align='center'><p>           <font color='#FF6600' size='3' face='Arial, Helvetica, sans-serif'>             We're sorry, but an error has occured !           </font></p><p>           <font size='2' face='Verdana, Arial, Helvetica, sans-serif'>           <strong>           Please try again later.           </strong></font><br><br>          <font size='2' face='Verdana, Arial, Helvetica, sans-serif'>           If you still have an error, please email our          <a href='mailto:techsupport@thedreamweaverhotel.com'>           Tech Support           </a> team, <br>          quoting the error details below and we'll do our best to help.           </font><br><br>           <font size='2' face='Courier New, Courier, mono'>         ";         echo ("$error_num : $error_string");         echo "           <br></font><br><strong>           <font size='3' face='Arial, Helvetica, sans-serif'>           The Dreamweaver Hotel Staff           </font></strong></p>          </div>           ";         exit;         }    }    ?> 

First of all, we check to see whether the error type is either E_ERROR or E_USER_ERROR, by checking $error_num, which is passed to the function by the PHP Engine.

If the error is of the E_ERROR or E_USER_ERROR type, the function displays a block of HTML code, which explains the error in a more professional user-friendly way.

The function then shows the contents of $error_num or $error_string, and then prints a closing block of HTML.

Lastly, as the E_ERROR or E_USER_ERROR types are fatal errors, we stop the script executing with the PHP exit command.

Now we have a custom error handling function, we can add the set_error_handler() function to our code.

The code below does this job:

    <?php          set_error_handler("customErrorHandler");    ?> 

As you can see from the above, we simply have to call the set_error_handler() function, giving it the name of our custom error handling function, customErrorHandler, as the parameter.

The last bit of code we are going to use is to manually trigger an error, so that we can see our custom error handler in action.

This is achieved by the following code:

    <?php          user_error("This is a test error", E_USER_ERROR);    ?> 

Next, we'll look at the results in our browser.

First we'll look at the normal PHP error handler in action, by triggering an E_USER_ERROR with the code above. The result is shown below:

click to expand

Next, we'll look at the result of our custom error handling function, by triggering the same error.

click to expand

Unfortunately, errors occurring are a fact of life, especially if you rely on external data or servers in your code. Using a custom error handler minimizes the damage, and maintains a professional look for your site.

Expanding On the Custom Error Handler

The previous example was quite simple, and there are a number of ways in which it can be extended.

One important addition that needs to be made is support for the other types of error, such as warnings and notices. It may be the case you don't want the user to see these, and instead they can be logged to a file. You could also set the fatal error types to have their details logged to a file, or even emailed to the developer; all you need to do is to put the relevant code in your error handling function.

The function could also be extended by logging the $error_context variable that is passed to the function, which contains all the variables in use at the time, and log these to a file.

Logging Errors That Occur

Errors can be logged to a file on the server if required, by writing them out as a standard text file. It's best to keep separate log files for each page, as although it's more files to monitor, it makes it easier to track down the cause of the error, if you're only seeing errors for that one particular page.

Because of security settings on the server, it's often easier if you create the log file yourself, and upload it to the server. Simply open a text editor, and then save the blank page as a new file, with the name of your log file.

For example, save an empty text file with the filename error3.txt, and upload it to the server. Before you can write to the file, you have to change its permissions level, so that your PHP script can open and add to the file. To do this you need to change the file's permissions to 666, using the chmod command for Linux. For Windows, you need to ensure that the file can be opened, read, and written to by the PHP engine.

The following code can be added to our custom error handler function and writes any errors occurring to a log file.

    <?php    // Set up variables, such as page name and time and date    $page_errorlog = "error3.txt";    $mytime = date("H:i:s");    $mydate = date("d.m.Y");    //Check file exists      if (file_exists($page_errorlog))     {        //open file for append        if ($logfile = fopen($page_errorlog,"a"))        {           // lock log file during write           flock($logfile, LOCK_EX);           // write error number, error string, and the time and date           fwrite($logfile,"$error_num : $error_string  :  $mytime  :  $mydate\n");           // unlock log file           flock($logfile, LOCK_UN);           // close log file           fclose($logfile);         }      }    ?> 

First of all, we put the filename of the log file for the page into the variable $page_errorlog. We then use the PHP date() function to put the current time and date into the variables $mytime and $mydate. The parameters for the PHP date function, and the other functions in this section of code can all be found in the PHP manual.

Note however that with functions such as the PHP date function, the case of the parameters matters. For example date("h") returns the current hour in 12-hour format (1 - 12 ), whereas date("H") would return the code in 24 hours format ( 0 - 23 ). All of the parameters can be found in the online documentation at http://www.php.net/, and it's useful to print them out for future reference.

We next check to see if our file exists using the PHP file_exists() function, and if it does, open it for appending, using the PHP fopen() function, passing the function the filename, and using the "a" mode, to append to the file. We then use the PHP function flock() to open an exclusive lock on the file, so that no one else can open it at the same time. We write the error number, error string, time, and date to the file using the PHP fwrite() function.

We then unlock the file, using flock() and close the file with the PHP function, fclose().

After triggering the test error we created a couple of times, the log file shows:

    256 : This is a test error  :  02:27:27  :  10.05.2002    256 : This is a test error  :  02:27:28  :  10.05.2002    256 : This is a test error  :  02:27:28  :  10.05.2002 

This will help you to see any errors that occur in day-to-day use, and track them down and fix them. Obviously the more data that is logged, the easier the process of finding the error is.

E-mailing Errors That Occur

In the first couple of days that your site goes "live", you may want more instant notifications of any errors that occur. In this case, you may prefer to have error information e-mailed direct to you. Be careful, though, to not set errors to be e-mailed to yourself until the site has gone through comprehensive testing, otherwise you could find your mailbox swamped with e-mailsl

To send an e-mail we use the PHP mail() function, the format for which is shown below:

    mail (to, subject, message [,additional_headers [,additional_parameters]]) 

mail() returns true if the e-mail is successfully sent, and false if it wasn't.

The piece of code shown below will e-mail the error details to the address specified in the code, and can be added to the error handler, or you could make it into a function which is called by the error handler.

    <?php      $errorpage = "error4.php";      $mytime = date("H:i:s");      $mydate = date("d.m.Y");      $to = "error@dreamweaverhotel.com";      $subject = "Error logged on page: $errorpage";      $message = "Error logged on page: $errorpage\n\n";      $message .= "Error Number $error_num, $error_string occurred at $mytime on    $mydate\n";      mail($to, $subject, $message);    ?> 

First of all we set up the variable to hold the page name, $errorpage, and variables $mytime and $mydate, for the time and date. We then set the $to with the recipient's e-mail address, $subject to the subject line, and $message to hold the message which is sent. Finally we send the e-mail with the mail() function:

    mail($to, $subject, $message); 

When an error is triggered, the following e-mail is sent.

     Error logged on page: error4.php     Error Number 256, This is a test error occurred at 03:19:17 on 10.05.2002 

It makes a lot of sense to turn the above code into a function, along with the previous error logging example, and store them in an include file specially for debugging. You can then add the include file to any pages that need debugging, and call the relevant function names from your error handler.

Re-enabling the Default PHP Error Handler

If you have set your own custom error handler using the set_error_handler() function, you can switch back to using the default PHP error handler using the function restore_error_handler().

The following code will set the error handler back to the default PHP handler.

    <?php      restore_error_handler();    ?> 

Suppressing Error Messages

To hide an error message temporarily if it occurs, you can use the @ directive. For example, look at the following piece of code:

    <?      $result = (10 / 0);    ?> 

When the page is opened in the browser, you get the following error message:

Warning 

Division by zero in /home/sites/site17/users/phpbook/web/errors/error5.php on line 9

This is expected as the code is attempting to divide 10 by 0. However, if we run the piece of code below:

    <?      $result = @(10 / 0);    ?> 

no error message is shown. It's important to remember that the error still occurs, so the remaining code might behave unpredictably.

Note that the @ is placed next to location where the error occurs, rather than at the front of the line. The @ directive cannot be used to ignore parse errors, only run-time errors.

Viewing Your Server Settings

If you're running your own PHP server, you probably have quite an accurate idea of what has been installed, and which settings are being used. If you don't run your own server, you will have less of an idea of the way it is set up. It can be a difficult task trying to find out what has and what hasn't been installed on a server which isn't your own, but help is at hand from the phpinfo() function.

phpinfo()

Open up a blank page, and add the following code to the page body, in Code view or using the Code inspector.

    <?php      phpinfo();    ?> 

Save the page, upload it to your server, and then open the page in your browser, and you will see a screen similar to the following.

click to expand

If you scroll downwards, you can see a list of all the PHP settings, and their values.

This information is incredible useful because it is so detailed. You can easily find your path info, whether a certain library is installed or not, as well as showing all the current settings.

Overriding Settings in the php.ini File Locally

It's worth noting that it is possible to change some of the PHP configuration options, on a local basis, if you cannot change php.ini. The following functions allow you to set and restore PHP configuration settings.

  • ini_set()

  • ini_get()

  • ini_restore()

You can look these functions up on the PHP or Zend web sites. They explain how to use the functions, and give a table of which configuration settings can be changed, and at which level.



Dreamweaver MX PHP Web Development
Dreamweaver Mx: Advanced Php Web Development
ISBN: 1904151191
EAN: 2147483647
Year: 2001
Pages: 88

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net