We already talked about PHP performance profiling by using the handy built-in xdebug profiler and passing the XDEBUG_PROFILE
parameter. You can find the original blog article here. But, that method does not give you an easy way to view the SQL calls you are making or the individual performance of those calls. To add a SQL performance profile to your database calls, we will create a wrapper class that will intercept each query and store the timing information and call that is being made. This wrapper is a drop in replacement for the original mysqli calls.
<?php
class debug_mysql extends mysqli {
const log_file = "/var/log/firephp.log";
public function query($sql, $file = "", $method = "", $line = "") {
global $is_dev;
global $debug_sql_flag;
if ($is_dev) {
$query_start = microtime(true);
$result = parent::query($sql);
$query_end = microtime(true);
$query_time = $query_end - $query_start;
if ($debug_sql_flag) {
if ($query_time > 10) {
$speed = "slow";
} else {
$speed = "normal";
}
if (!$result) {
$err = "ERROR: $this->error";
} else {
$err = "Ok";
}
$db = $this->get_database_name();
self::log_to_file("QUERY: $query_time ms, $speed, $db, $sql, $err", $file,$method,$line);
}
return $result;
} else {
return parent::query($sql);
}
}
public function get_database_name() {
$str = "{unknown db}";
if ($result = parent::query("SELECT DATABASE()")) {
$row = $result->fetch_row();
$str = $row[0];
$result->close();
}
return $str;
}
public static function log_to_file($str, $file = "", $method = "", $line = "") {
file_put_contents(self::log_file, $file."::".$method."[".$line."] -
\"".$str."\"\n", FILE_APPEND);
}
}
?>
This gives you a log file that stores all of your SQL commands and can be imported as a CSV file into Excel for sorting or other analysis. SQL error messages are captured along with the location in the code the call was made from (provided you pass them along).
If you are running the server on Linux, you can simply open a shell session and run:
tail -f /var/log/firephp.log
You can watch this terminal window show all your queries along with the time it takes to execute each query. Any SQL errors that are found will display along with the error information. This helps for quick debugging if you just want to find out if your queries are running properly.
Instead of displaying to a log file, it can be useful to output the log to FirePHP. FirePHP allows you to display debug information to your Firebug console through the Firefox web browser. It can certainly be handy if you don't want to or can't open up a shell connection. Install FirePHP using pear as described on the FirePHP website and install the FirePHP Firefox extension to your browser.
To display to FirePHP instead of a file, replace the log_to_file()
function with the code below. This way, you can have SQL code show right in your browser.
public static function log_to_file
($str, $file = "", $method = "", $line = "") {
$firephp = FirePHP::getInstance(true);
$firephp->log($file."::".$method."[".$line."] - \"".$str."\"");
}
Always be careful not to show debug information on a production system. At best, it is a sloppy practice and at worst, it can reveal sensitive system data.