In my opinion, the best thing about working in the development phase is the liberty to throw your errors to the browser, without too many worries of prying eyes. Once your project is live, however, these errors can be very risky business and naturally they should be supressed. This carries with it the disadvantage of complicating the debugging process if something goes wrong. One great way to suppress these demons, without losing any valuable information, is to log your errors to a private file on the server.
In this article I will show you a very basic way of logging to your own file using PHP's logging functions. It is intended only as a start and by no means a complete thesis on logging as a whole. I intend to continue the discussion in follow up articles as time allows, so please check back often.

How It's Done

First we declare two variables containing the info for our log file and the date in our desired format. This will make things easier if we need to change the location, the filename and/or the date format at a later time. In this example I will use /tmp/article.log because I am using my development machine. Please, do not use /tmp on a production machine. Instead, have your admin s et up a directory outside of the DocumentRoot that the server can write to, and you can read. /tmp is normally chmod 777, meaning that anyone can read, write or execute from that directory. This can be a major security hazard.
With that said, we declare the variables:

<?php
$log_file 
'/tmp/article.log';
$date date('Y-m-d H:i:s (T)');
?>
Next, we create a function for handling the errors. To keep things simple, I will provide a very basic example. Of course, you are free to expand on this as you wish:

<?php
function simplisticErrorHandler($errno$errmsg$filename$linenum$vars)
{
    global 
$log_file$date;
    if ( 
$errno == E_USER_NOTICE )
    {
        
$error "$date - ".$_SERVER['REMOTE_ADDR']." - NOTICE: $errmsg in $filename on line $linenum\n";
        
error_log$error3$log_file );
    }
}
?>
This function will handle only the errors that you trigger and is pretty cut and dry, so I won't go into detail. If you are having a bit of an issue it's probably best that you drop back a little, until you are a little more familiar with PHP.
The key player in this function is error_log(), which takes 3 arguments: the message you want logged, the way we want the error handled and finally the destination. The first argument is pretty self-explanatory, as is the third. The second argument determines how PHP handles logging the file and, taken from http://www.php.net/error_log, our current options are:
- 0 message is sent to PHP's system logger, using the Operating System's system logging mechanism or a file, depending on what the error_log configuration directive is set to.
- 1 message is sent by email to the address in the destination parameter. This is the only message type where the fourth parameter, extra_headers is used. This message type uses the same internal function as mail() does.
- 2 message is sent through the PHP debugging connection. This option is only available if remote debugging has been enabled. In this case, the destination parameter specifies the host name or IP address and optionally, port number, of the socket receiving the debug information.
- 3 message is appended to the file destination.
So, naturally, in our case #3 is our destination of choice.

Breaking the right rules

Ok, so we have our function ready to go for handling our logging calls. The next order of business is to tell the parser that it should use this function for handling any errors. To do this, we will use the set_error_handler() function as so:

<?php
set_error_handler
("simplisticLoggingFunction");
?>
Now, in order to see any results during this demonstration, we'll need to create our own error. To do this, I'll use a simple in_array() on a string variable. So, first we declare a variable with a string value:

<?php
$fake_array 
'test';
?>
Next, I will create an if statement which will throw an error by testing our faked array for the key 'Something':

<?php
if ( !in_array'Something'$fake_array ) ) 
{
    
trigger_error("Humph, you and I both know that wasn't an array"E_USER_NOTICE); 
    echo 
"An error has been posted to $log_file";
}
?>
Full Source!
Here is the code in whole so that you may paste it in a file for demonstration purposes:

<?php
$log_file 
'/whatever.file';  // change this to a file the server can write to, and you can read
$date date('Y-m-d H:i:s (T)');
function 
simplisticErrorHandler($errno$errmsg$filename$linenum$vars)
{
    global 
$log_file$date;
    if ( 
$errno == E_USER_NOTICE )
    {
        
$err "$date - ".$_SERVER['REMOTE_ADDR']." - NOTICE: $errmsg in $filename on line $linenum\n";
        
error_log($err,3,$log_file);
    }
}

set_error_handler("simplisticErrorHandler");

$fake_array 'test'// declare the variable with a string value;
if ( !in_array('Something'$fake_array ) ) // cause the faked array to throw an error
{
    
trigger_error("Look, you and I both know that wasn't an array",E_USER_NOTICE); 
    echo 
"An error has been posted to $log_file";
}
?>
Once you have pasted the above code into a file, you can open that file in your browser and it should print an error to your log file, as well as echo "An error has been posted to /tmp/article.log" to your browser. If this is not the case, there may be a permissions problem, or you may need to check your syntax.

Added Advantages

I particularly like logging my errors to files because you can always open a shell on Linux/Unix and do 'tail -f /tmp/article.log' to view any errors in real time. Even if the site is not in a production state it can still be of great benefit, provided your error handling is detailed enough to lead you to the cause.
Another great advantage of logging to a file: if you have access to the config file for the Linux/Unix binary 'logrotate', you can rotate these files automatically. This will prevent them from growing too big and will provide an archive over several weeks or months.
Ciao
As stated, this is intended for the beginner programmer and is only one of a whole plethora of ways to log your errors. The above example will log only the errors you send to it, which is obviously not the most optimal way to handle your errors. In the next article, I will delve into errors that come directly from the PHP parser.
I hope this helps! Til next time....