do_query() is a replacement for mysql_query in PHP, providing help with debugging of MySQL queries, and notification from your site when something goes wrong.
Usage is quite simple. First, you must define the two variables at the top of the script, client name and email address. The client name is only useful if you manage several sites, and the email address is where you wish to have error notifications send. You need to include the function itself on each page you wish to use it. Normally, a developer will have a selection of functions in one file, then include that file on every page - and that's where to add this to.
To call it, you replace the "mysql_query" function call with "do_query" function call, and add "__LINE__" towards the end. The addition of the "__LINE__" variable at the end of the call means that rather than needing to hunt through an entire script once the system has informed you of an error, you can see exactly where it is called from. The two boxes below demonstrate, first, the usual way to execute a query and, second, how to execute a query with do_query.
$result = mysql_query("SELECT * FROM table");
$result = do_query("SELECT * FROM table", __LINE__);
If the query executes correctly, you will see no difference in the running of the site. On any error though, the system (instead of the usual message from MySQL) will display a customised error notification telling the user you have been informed of the error. The system will also email you to tell you the file name and line on which the error occurred, and send you the query that made it fail.
The other purpose of do_query is to aid in debugging of script that isn't behaving itself, specifically by actually showing any queries on the page itself. Simply add "debug=1" to your querystring, and any query executed on the page using do_query will be displayed, along with the number of results returned, hopefully allowing you to spend more time fixing bugs and less time hunting them down.
function do_query($sql, $line) {
$client = ""; // Client Name
$email = ""; // Email to notify on error
$result = @mysql_query($sql);
$total = @mysql_num_rows($result);
if (@mysql_error() <> "") {
echo " <br><font face=\"Verdana\" size=\"1\"><small><b><p align=\"center\">Sorry, there has been an unexpected database error. The webmaster has been informed of this error.</p></b></small></font>";
// Error number
$error_message = "<table border=\"0\" cellpadding=\"3\" cellspacing=\"1\" style=\"border: 1px solid #bbbbbb;\" bgcolor=\"#ffffff\" width=\"80%\" align=\"center\"><tr><td align=\"right\" width=\"25%\"><font face=\"Verdana\" size=\"1\"><small><b>Error Number:</b></small></font></td><td width=\"75%\"><font face=\"Verdana\" size=\"1\"><small>" . @mysql_errno() . "</small></font></td></tr>";
// Error Description
$error_message .= "<tr><td align=\"right\"><font face=\"Verdana\" size=\"1\"><small><b>Error Description:</b></small></font></td><td><font face=\"Verdana\" size=\"1\"><small>" . @mysql_error() . "</small></font></td></tr>";
// Error Date / Time
$error_message .= "<tr><td align=\"right\"><font face=\"Verdana\" size=\"1\"><small><b>Error Time:</b></small></font></td><td><font face='Verdana' size='1'><small>" . date("H:m:s, jS F, Y") . "</small></font></td></tr>";
// Client
$error_message .= "<tr><td align=\"right\"><font face=\"Verdana\" size=\"1\"><small><b>Client:</b></small></font></td><td><font face=\"Verdana\" size=\"1\"><small>" . $client . "</small></font></td></tr>";
// Script
$error_message .= "<tr><td align=\"right\"><font face=\"Verdana\" size=\"1\"><small><b>Script:</b></small></font></td><td><font face=\"Verdana\" size=\"1\"><small>" . $_SERVER["SCRIPT_NAME"] . "</small></font></td></tr>";
// Line Number
$error_message .= "<tr><td align=\"right\"><font face=\"Verdana\" size=\"1\"><small><b>Line:</b></small></font></td><td><font face=\"Verdana\" size=\"1\"><small>" . $line . "</small></font></td></tr></table>";
// SQL
$error_message .= "<table border=\"0\" cellpadding=\"3\" cellspacing=\"1\" style=\"border: 1px solid #bbbbbb;\" bgcolor=\"#ffffff\" width=\"80%\" align=\"center\"><tr><td align=\"right\"><font face=\"Verdana\" size=\"1\"><small><b>Query:</b></small></font></td><td><font face=\"Verdana\" size=\"1\"><small>" . $sql . "</small></font></td></tr>";
$error_message .= "<tr><td align=\"right\" valign=\"top\" width=\"25%\"><font face=\"Verdana\" size=\"1\"><small><b>Processes:</b></small></font></td><td><font face=\"Verdana\" size=\"1\"><small>";
$result = @mysql_list_processes();
while ($row = @mysql_fetch_assoc($result)){
$error_message .= $row["Id"] . " " . $row["Command"] . " " . $row["Time"] . "<br>";
}
@mysql_free_result($result);
$error_message .= "</small></font></td></tr></table>";
$headers = "From: \"MySQL Debug\" <" . $email . ">\r\n";
$headers .= "Content-Type: text/html; charset=ISO-8859-1\r\n";
//mail($email, "[MySQL Error] ". $client, $error_message, $headers);
die();
}
if ($_GET["debug"]=="1") {
echo "<div width=\"100%\" style=\"margin: 10px; margin-bottom: 0; padding: 3px; border: 1px solid #ff0000; background-color: #ffffff; font: 10px verdana; overflow: auto;\">".$sql."</div><div width=\"100%\" style=\"margin: 10px; margin-top: 0; padding: 3px; border: 1px solid #ff0000; background-color: #ff0000; font: 10px verdana; color: #ffffff; font-weight: bold;\">" . $total . " rows found.</div>";
}
return $result;
}
13 Comments
This is pretty cool.
Only one thing I would change - is use of CSS in order to format ouptput tables.
#1, Alexander, Canada, 13 May 2005. Reply to this.
what do you mean by "add "debug=1" to your querystring?"
I already have a string there (viewdb?acct=xxxxx)
peterna@adabyron.net
#2, Peter Namtvedt, United States, 26 July 2005. Reply to this.
Hi Peter. To debug, you'd use the URL: viewdb?acct=xxxxx&debug=1
#3, Dave Child, United Kingdom, 27 July 2005. Reply to this.
What about those of us using various db abstractions ?
#4, Chris Neale, United Kingdom, 10 January 2007. Reply to this.
Strip those ugly tables off and it is one handy function :)
#5, LKRaider, Brazil, 16 March 2007. Reply to this.
LKRaider: I should probably either retire this or update it - the code is far older than the article and the site of that HTML now makes me shudder :).
#6, Dave Child, United Kingdom, 19 March 2007. Reply to this.
One of the things i love about browsing the web is finding inspiration and new methods.
i've always added error reporting codes in the "or die( 'messages, and codes here' . mysql_error())" after the query call.
once again, thanks for some nice info !
#7, Loke Krongaard Hansen, Denmark, 24 May 2007. Reply to this.
very nice peace of code, works a treat thanks :)
#8, muLLet, United Kingdom, 13 June 2007. Reply to this.
hi if u have more debugging tech. for php and mysql so please reply me on cgadgilwar@gmail.com
#9, chetan, Unknown, 25 March 2008. Reply to this.
Thanks for this function, it got me out of a hole!
#10, Charlie, Unknown, 7 January 2009. Reply to this.
Is there any software or tool for debugging the MySql query. Which would we better when query goes to more the 100 Sub queries.
Please specify me
#11, Vikas Gupta, Unknown, 23 June 2009. Reply to this.
Thanks for that! It debugged my problem, where I wasn't getting an error at all and should have.
#12, Yecats Ffoeg, Ireland, 24 November 2010. Reply to this.
If you dont want to pass the linenumber everytime you can use this function
function getline($dbt){
$edbt = end($dbt)
return $edbt['line'];
}
When you want to see the linenumber write this:
echo 'Line:'. getline(debug_backtrace())
#13, Julius, Magnifisite, 20 March 2012. Reply to this.