Error and Exception Handling in PHP

Mistakes are inevitable, in life, programming, and application submissions. You can prepare for errors by making sure your application is designed to respond to them. This two-part article explains how PHP handles errors. It is excerpted from chapter 8 of the book Beginning PHP and Oracle: From Novice to Professional, written by W. Jason Gilmore and Bob Bryla (Apress; ISBN: 1590597702).

Even if you wear an S on your chest when it comes to programming, you can be sure that errors will creep into all but the most trivial of applications. Some of these errors are programmer-induced—they are the result of mistakes made during the development process. Others are user-induced, caused by the end user’s unwillingness or inability to conform to application constraints. For example, the user might enter 12341234 when asked for an e-mail address, obviously ignoring what would otherwise be expected as valid input. Yet regardless of the source of the error, your application must be able to encounter and react to such unexpected errors in a graceful fashion, hopefully doing so without losing data or crashing the application. In addition, your application should be able to provide users with the feedback necessary to understand the reason for such errors and potentially adjust their behavior accordingly.

This chapter introduces several features PHP has to offer for handling errors. Specifically, the following topics are covered:

Configuration directives: PHP’s error-related configuration directives determine the bulk of the language’s error-handling behavior. Many of the most pertinent directives are introduced in this chapter.

Error logging: Keeping a running log is the best way to record progress regarding the correction of repeated errors, as well as quickly identify newly introduced problems. In this chapter, you learn how to log messages to both your operating system syslog and a custom log file.

Exception handling: Prevalent among many popular languages (Java, C#, and Python, to name a few), exception handling was added to PHP with the version 5 release. Exception handling offers a standardized process for detecting, responding to, and reporting errors.

Historically, the development community has been notoriously lax in implementing proper application error handling. However, as applications continue to grow increasingly complex and unwieldy, the importance of incorporating proper error-handling strategies into your daily development routine cannot be overstated. Therefore, you should invest some time becoming familiar with the many features PHP has to offer in this regard.

{mospagebreak title=Configuration Directives}

Numerous configuration directives determine PHP’s error-reporting behavior. Many of these directives are introduced in this section.

Setting the Desired Error Sensitivity Level

The error_reporting directive determines the reporting sensitivity level. Fourteen separate levels are available, and any combination of these levels is valid. See Table 8-1 for a complete list of these levels. Note that each level is inclusive of all levels residing below it. For example, the E_ALL level reports any messages resulting from the 13 other levels residing below it in the table.

Table 8-1. PHP’s Error-Reporting Levels  

Error Level

Description

E_ALL

All errors and warnings

E_COMPILE_ERROR

Fatal compile-time errors

E_COMPILE_WARNING

Compile-time warnings

E_CORE_ERROR

Fatal errors that occur during PHP’s initial start

E_CORE_WARNING

Warnings that occur during PHP’s initial start

E_ERROR

Fatal run-time errors

E_NOTICE

Run-time notices

E_PARSE

Compile-time parse errors

E_RECOVERABLE_ERROR

Near-fatal errors (introduced in PHP 5.2)

E_STRICT

PHP version portability suggestions (introduced in PHP 5.0)

E_USER_ERROR

User-generated errors

E_USER_NOTICE

User-generated notices

E_USER_WARNING

User-generated warnings

E_WARNING

Run-time warnings

Introduced in PHP 5, E_STRICT suggests code changes based on the core developers’ determinations as to proper coding methodologies and is intended to ensure portability across PHP versions. If you use deprecated functions or syntax, use references incorrectly, use var rather than a scope level for class fields, or introduce other stylistic discrepancies, E_STRICT calls it to your attention. In PHP 6, E_STRICT is integrated into E_ALL ; therefore, when running PHP 6, you’ll need to set the error_reporting directive to E_ALL in order to view these portability suggestions.


Note  The error_reporting directive uses the tilde character ( ~ ) to represent the logical operator NOT .


During the development stage, you’ll likely want all errors to be reported. Therefore, consider setting the directive like this:

error_reporting = E_ALL

However, suppose that you were only concerned about fatal run-time, parse, and core errors. You could use logical operators to set the directive as follows:

error_reporting E_ERROR | E_PARSE | E_CORE_ERROR

As a final example, suppose you want all errors reported except for user-generated ones:

error_reporting E_ALL & ~(E_USER_ERROR | E_USER_WARNING | E_USER_NOTICE)

As is often the case, the name of the game is to remain well-informed about your application’s ongoing issues without becoming so inundated with information that you quit looking at the logs. Spend some time experimenting with the various levels during the development process, at least until you’re well aware of the various types of reporting data that each configuration provides.

{mospagebreak title=Displaying Errors to the Browser}

Enabling the display_errors directive results in the display of any errors meeting the criteria defined by error_reporting . You should have this directive enabled only during testing and keep it disabled when the site is live. The display of such messages not only is likely to further confuse the end user but could also provide more information about your application/server than you might like to make available. For example, suppose you are using a flat file to store newsletter subscriber e-mail addresses. Due to a permissions misconfiguration, the application could not write to the file. Yet rather than catch the error and offer a user-friendly response, you instead opt to allow PHP to report the matter to the end user. The displayed error would look something like this:

——————————————–

Warning: fopen(subscribers.txt): failed to open stream: Permission denied in
/home/www/htdocs/ 8/displayerrors.php on line 3

——————————————–

Granted, you’ve already broken a cardinal rule by placing a sensitive file within the document root tree, but now you’ve greatly exacerbated the problem by informing the user of the exact location and name of the file. The user can then simply enter a URL similar to http://www.example.com/subscribers.txt and proceed to do what he will with your soon-to-be furious subscriber base.

Displaying Startup Errors

Enabling the display_startup_errors directive will display any errors encountered during the initialization of the PHP engine. Like display_errors , you should have this directive enabled during testing and disabled when the site is live.

Logging Errors

Errors should be logged in every instance because such records provide the most valuable means for determining problems specific to your application and the PHP engine. Therefore, you should keep log_errors enabled at all times. Exactly to where these log statements are recorded depends on the error_log directive.

Identifying the Log File

Errors can be sent to the system syslog or can be sent to a file specified by the administrator via the error_log directive. If this directive is set to syslog, error statements will be sent to the syslog on Linux or to the event log on Windows.

If you’re unfamiliar with the syslog, it’s a Linux-based logging facility that offers an API for logging messages pertinent to system and application execution. The Windows event log is essentially the equivalent of the Linux syslog. These logs are commonly viewed using the Event Viewer.

Setting the Maximum Log Line Length

The log_errors_max_len directive sets the maximum length, in bytes, of each logged item. The default is 1,024 bytes. Setting this directive to 0 means that no maximum length is imposed.

Ignoring Repeated Errors

Enabling ignore_repeated_errors causes PHP to disregard repeated error messages that occur within the same file and on the same line.

Ignoring Errors Originating from the Same Location

Enabling ignore_repeated_source causes PHP to disregard repeated error messages emanating from different files or different lines within the same file.

Storing Most Recent Error in a Variable

Enabling track_errors causes PHP to store the most recent error message in the variable $php_errormsg . Once registered, you can do as you please with the variable data, including output it, save it to a database, or do any other task suiting a variable.

{mospagebreak title=Error Logging}

If you’ve decided to log your errors to a separate text file, the Web server process owner must have adequate permissions to write to this file. In addition, be sure to place this file outside of the document root to lessen the likelihood that an attacker could happen across it and potentially uncover some information that is useful for surreptitiously entering your server.

You have the option of setting the error_log directive to the operating system’s logging facility (syslog on Linux, Event Viewer on Windows), which will result in PHP’s error messages being written to the operating system’s logging facility or to a text file. When you write to the syslog, the error messages look like this:

——————————————–

Dec 5 10:56:37 example.com httpd: PHP Warning:
fopen(/home/www/htdocs/subscribers.txt): failed to open stream: Permission
denied in
/home/www/htdocs/book/8/displayerrors.php on line 3

——————————————–

When you write to a separate text file, the error messages look like this:

——————————————–

[05-Dec-2005 10:53:47] PHP Warning:
fopen(/home/www/htdocs/subscribers.txt): failed to open stream: Permission
denied in
/home/www/htdocs/book/8/displayerrors.php on line 3

——————————————–

As to which one to use, that is a decision that you should make on a per-environment basis. If your Web site is running on a shared server, using a separate text file or database table is probably your only solution. If you control the server, using the syslog may be ideal because you’d be able to take advantage of a syslog-parsing utility to review and analyze the logs. Take care to examine both routes and choose the strategy that best fits the configuration of your server environment.

PHP enables you to send custom messages as well as general error output to the system syslog. Four functions facilitate this feature. These functions are introduced in this section, followed by a concluding example.

{mospagebreak title=Initializing PHP’s Logging Facility}

The define_syslog_variables() function initializes the constants necessary for using the openlog() , closelog() , and syslog() functions. Its prototype follows:

void define_syslog_variables(void)

You need to execute this function before using any of the following logging functions.

Opening the Logging Connection

The openlog() function opens a connection to the platform’s system logger and sets the stage for the insertion of one or more messages into the system log by designating several parameters that will be used within the log context. Its prototype follows:

int openlog(string ident, int option, int facility)

Several parameters are supported, including the following:

ident : Identifies messages. It is added to the beginning of each entry. Typically this value is
se t to the name of the program. Therefore, you might want to identify PHP-related messages such as “PHP” or “PHP5.”

option : Determines which logging options are used when generating the message. A list of available options is offered in Table 8-2. If more than one option is required, separate each option with a vertical bar. For example, you could specify three of the options like so:
LOG_ODELAY | LOG_PERROR | LOG_PID .

facility : Helps determine what category of program is logging the message. There are several categories, including LOG_KERN , LOG_USER , LOG_MAIL , LOG_DAEMON , LOG_AUTH , LOG_LPR , and LOG_LOCALN, where N  is a value ranging between 0 and 7. Note that the designated facility determines the message destination. For example, designating LOG_CRON results in the submission of subsequent messages to the cron log, whereas designating LOG_USER results in the transmission of messages to the messages file. Unless PHP is being used as a command-line interpreter, you’ll likely want to set this to LOG_USER . It’s common to use LOG_CRON when executing PHP scripts from a crontab. See the syslog documentation for more information about this matter.

Table 8-2. Logging Options  

Option

Description

LOG_CONS

If an error occurs when writing to the syslog, send output to the system console.

LOG_NDELAY

Immediately open the connection to the syslog.

LOG_ODELAY

Do not open the connection until the first message has been submitted for logging. This is the default.

LOG_PERROR

Output the logged message to both the syslog and standard error.

LOG_PID

Accompany each message with the process ID (PID).

Closing the Logging Connection

The closelog() function closes the connection opened by openlog() . Its prototype follows:

int closelog(void)

{mospagebreak title=Sending a Message to the Logging Destination}

The syslog() function is responsible for sending a custom message to the syslog. Its prototype follows:

int syslog(int priority, string message)

The first parameter, priority , specifies the syslog priority level, presented in order of severity here:

LOG_EMERG : A serious system problem, likely signaling a crash

LOG_ALERT : A condition that must be immediately resolved to avert jeopardizing system integrity

LOG_CRIT : A critical error, which could render a service unusable but does not necessarily place the system in danger

LOG_ERR : A general error

LOG_WARNING : A general warning

LOG_NOTICE : A normal but notable condition

LOG_INFO : A general informational message

LOG_DEBUG : Information that is typically only relevant when debugging an application

The second parameter, message , specifies the text of the message that you’d like to log. If you’d like to log the error message as provided by the PHP engine, you can include the string %m in the message. This string will be replaced by the error message string ( strerror ) as offered by the engine at execution time.

Now that you’ve been acquainted with the relevant functions, here’s an example:

<?php
    define_syslog_variables();
    openlog("CHP8", LOG_PID, LOG_USER);
    syslog(LOG_WARNING,"Chapter 8 example warning.");
    closelog();
?>

This snippet would produce a log entry in the messages syslog file similar to the following:

——————————————–

Dec 5 20:09:29 CHP8[30326]: Chapter 8 example warning.

——————————————–

 

 

Please check back Monday for the conclusion to this article.

[gp-comments width="770" linklove="off" ]

chat sex hikayeleri Ensest hikaye