Forum Moderators: coopster

Message Too Old, No Replies

php functions die() and trigger error() Pro's and Con's of?

         

Matthew1980

7:00 pm on Sep 9, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hi there all!

I recently discovered that a few people use: or trigger_error(mysql_error(), E_USER_ERROR) opposed to using: or die(mysql_error()) on the end of any sql function.

My question is, which is better, or is it down to preference? I personally don't use the former, I have always used the latter as it was the method I was taught to use.

Thoughts?

Cheers,
MRb

JAB Creations

1:34 pm on Sep 10, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Oh man, I only use PHP's die() in two instances the first of which is when the user is loading pages too quickly. I actually capture all MySQL errors and log them to MySQL...or as a fall back to a flat-file log.

The only other instance I use die() is when I send an HTTP 304 response as I found a nasty bug in Gecko browsers. See this page for the bug:
[bugzilla.mozilla.org ]. Basically Gecko does not correctly interpret pages that have content even if their HTTP response is 304 so just in case your code is somehow sending content after the HTTP 304 header use die() to seal the deal. It sure was one of those exceptionally rare days where the solution was as simple as saying, 'die'. :)

Logging errors is pretty important and I log everything. Here is an example of the general format I go with. I also recommend using Tail32 if you're on Windows to see real time log of your queries. :)

- John

<?php
error_reporting(E_ALL);

function mysql_error_report($q,$e,$f)
{
if (isset($_SESSION['id_user'])) {$id = $_SESSION['id_user'];} else {$id = 0;}
if ($_SESSION) {$session = mysql_real_escape_string(session_id());} else {$session = 0;}
$ip = mysql_real_escape_string(getenv('REMOTE_ADDR'));

$query = mysql_real_escape_string($q);
$error = mysql_real_escape_string($e);
$function = mysql_real_escape_string($f);

$query1 = "INSERT INTO log_mysql_errors (id_session, id_user, date, ip, function, mysql_error, mysql_query) VALUES ('$session', '$id', NOW(), inet_aton('$ip'), '$function', '$error', '$query')";
$result1 = mysql_query($query1);
}

$query1 = "SELECT * FROM example;";
$result1 = mysql_query($query1);

if ($result1)
{
echo 'and there was much rejoicing';
}
else {mysql_error_report($query1,mysql_error(),__FUNCTION__);}
?>

[edited by: dreamcatcher at 7:46 am (utc) on Sep 12, 2010]
[edit reason] Removed side scroll [/edit]

Matthew1980

7:32 am on Sep 12, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hi there JAB Creations,

Wow! thanks for the template, I have been thinking of doing this for a while, at least using this method you can do other things with the script and pipe the error to a DB log, though I think that I would pipe the information to a text file just in case the DB was down for any reason.

Then whilst this action was going on you could redirect the user to another page saying a generic error message (for a few seconds, suggesting they try again later) then redirect back to the homepage, at least you would still have the traffic on your site...

Cheers,
MRb

penders

4:53 pm on Sep 12, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I recently discovered that a few people use: or trigger_error(mysql_error(), E_USER_ERROR) opposed to using: or die(mysql_error()) on the end of any sql function.


die() will halt your script and output the error directly to the client - possibly meaningless to your end users. In a production environment I would have thought this should always be avoided. I think the use of die() in code examples is just a quick (and dirty) way of triggering an error state and halting the script. It should perhaps read "/* Insert your error handling code here */"

trigger_error() in combination with a custom error handler [php.net] can be set to output the error and/or log it to a file (standard error.log / db). In the error handler you can optionally halt your script if you want, redirect to an error page, etc... Your end user should be unaware of the true nature of the error.

The only other instance I use die() is when I send an HTTP 304 response as I found a nasty bug in Gecko browsers. ... Basically Gecko does not correctly interpret pages that have content even if their HTTP response is 304 so just in case your code is somehow sending content after the HTTP 304 header use die() to seal the deal.


The HTTP spec states that a 304 response should not contain a message body, so exit() is probably always advisable in this situation. You probably don't want to be executing any unnecessary server-side code either.

JAB Creations

5:14 pm on Sep 12, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Oh yeah there is PHP error handling too which I also log. ;)

Also I test things very rigorously so in example when I test locally with XAMPP I use it's control panel to disable MySQL and test how the site works. I will eventually have flat file fallback (and maybe even replace direct fetching to the database even?) though I simultaneously have all error reporting set to the maximum sensitivity and then capture those errors so the user never sees an error. I disable MySQL and ensure that the site falls back to "safe mode" which with Version 2.9.0 of my site won't display content...again I'll eventually add flat file fallback support for. When the database is down my site then triggers a robots.txt and meta robots override to prevent spiders from crawling the safe mode version of pages. Users won't see content though they will know that the site still exists. This is for the personal version of my site of course. I disable all sorts of things in every combination that I can think of to break my work in any way I can and then work to ensure that there aren't any error messages leaking out or the site isn't visible in a way the user doesn't understand. That includes disabling cache, cookies, JavaScript, headers, MySQL etc...of course if Apache is disabled then there is no way around that unless you have a multi-server setup like M$. :D

penders is right on about die() in PHP hence why I only use it in those two specific scenarios (though I'm always willing to listen to what others have to say in the matter).

The following I declare in my master header file...

- John

<?php

set_error_handler('error_handle');

function error_handle($errno,$errstr,$errfile,$errline,$errcontext)
{
if (isset($db))
{
$session = mysql_real_escape_string(session_id());
if (isset($_SESSION['user_id'])) {$user = mysql_real_escape_string($_SESSION['user_id']);}
else {$user = 0;}
$ip = mysql_real_escape_string(getenv('REMOTE_ADDR'));
$error = mysql_real_escape_string($errstr);

$fil = explode('Site Name Here\\',$errfile);
$file = mysql_real_escape_string('Line '.$errline.' in '.$fil[1]);
$query1 = "INSERT INTO log_php_errors (id_session, id_user, date, ip, error, file) VALUES ('$session', '$user', NOW(), '$ip', '$error', '$file')";
$result1 = mysql_query($query1);

if ($result1) {}
else {mysql_error_report($query1,mysql_error(),__FUNCTION__);}
}

/*
FILE SYSTEM
// Linux CHMOD 606
if ($_SERVER['SERVER_NAME']=='www.example.com') {$fp = fopen('/home/example/php_errors.log', 'a+');}
else if ($_SERVER['SERVER_NAME']=='localhost') {$fp = fopen('D:\MEDIA\DOCUMENTS\Web Folder Goes Here\php_errors.log', 'a+');}

if ($fp)
{
fwrite($fp, date('Y-m-d g:i:sA').': '.$errstr."\n");
//fwrite($fp, $errno."\n");
//fwrite($fp, $errstr."\n");
fwrite($fp, 'Line '.$errline.' in '.$errfile."\n\n\n");
//fwrite($fp, ."\n");
//fwrite($fp, $errcontext."\n\n\n");
//fwrite($fp, print_r($errcontext, true)."\n\n\n");
fclose($fp);
}
*/
}

?>

JAB Creations

5:32 pm on Sep 12, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Oh Penders...in the HTTP 304 situation using exit only has a limited effect I think. Like if you're inside a function or class it'll only exit that portion but PHP will still execute whereas by using die() in that scenario you effectively kill off all of the PHP processing at that exact point. That is my current understanding of the difference between exit() and die().

- John

penders

8:27 pm on Sep 12, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



AFAIK die() [uk.php.net] and exit() are the same, there is no difference - one is an alias of the other. (?) The PHP manual does state "die — Equivalent to exit()".

exit() certainly terminates the script, even when used inside a function.

I have always assumed that the use of die() in such code examples was just for readability?

Matthew1980

8:33 pm on Sep 12, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hi all,

I only use exit; to escape from things, or terminate process' I only use die in the context of mysql_error(). But since asking this question, I am going to write myself a little 'piping' class so that I can have complete control over my error log, I would prefer doing this through a flat text file, as DB's can go down.

I'll post something once I have written it, may be of some use to someone after all. I can't believe as I never though of doing this before now, something that is taken for granted I guess, as we are taught/learn to get things right by doing a lot of alpha/beta testing - well that's my excuse anyway!

Thanks for all the thought's anyway.

Cheers,
MRb

JAB Creations

8:42 pm on Sep 12, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I have used exit() in the past...though you guys have to admit, telling the computer to die() is just too much fun to pass up! ;)

Matthew, do what I did and take an hour or two going through your work and replace that die with the following code below. I use Advanced Find and Replace which is absolutely invaluable for quickly running through things.

- John

<?php
function example()
{
$query1 = "";
$result1 = mysql_query($query1);

if ($result1)
{
$query2 = "";
$result2 = mysql_query($query2);

if ($result2)
{
// stuff
}
else {mysql_error_report($query2,mysql_error(),__FUNCTION__);}
}
else {mysql_error_report($query1,mysql_error(),__FUNCTION__);}

}
?>