PHP debug tools
Download
Examples
- Debug script trace (dependency: xdebug php extension)
- Debug errors
- Debug using debug() function
- Debug using dump(), dump_tofile() functions
- Debug database queries
Example 1: debug script trace
To use trace debugging script you need to:
- Install xdebug php extension.
- chmod /dev/data/ directory so it is writable.
Xdebug install
How to install docs: http://www.xdebug.org/docs/install
Example installation (for windows, tested with xdebug version 2.0.4, php version 5.2.8, nts non-thread safe):
- Download xdebug from: http://www.xdebug.org/download.php
- Copy dll to php extensions directory, for example: C:/php/ext/php_xdebug-2.0.4-5.2.8-nts.dll
- Add this directives to php.ini:
This example is for non-thread safe version. For the thread safe version change "zend_extension" to "zend_extension_ts".zend_extension = "C:/php/ext/php_xdebug-2.0.4-5.2.8-nts.dll" xdebug.collect_includes = Off xdebug.default_enable = Off xdebug.dump_globals = Off xdebug.dump_once = Off xdebug.extended_info = Off
Input
<?php
include './auto_prepend.php';
echo '<h1>test3: trace</h1>';
function test1()
{
test2();
}
function test2()
{
for ($i = 0; $i < 100; $i++) {
$s = substr('', 0, 1);
}
}
test1();
include './auto_append.php';
?>
Output
In the bottom-right corner will be displayed a debug console, which shows execution time of php script along with used memory. The "start" link enables xdebug session, after the session is enabled you have to click "xdebug-trace" link to view the script trace in a popup window.
Step 1 - click "start" to enable xdebug session
Step 2 - click "xdebug-trace" to open popup window
Step 3 - xdebug-trace popup window
More info
Including debug console in all scripts on localhost
You can set php.ini directives "auto_prepend_file" & "auto_append_file" to point to auto_prepend.php & auto_append.php files, and you will see the debug console in each script that you are running on your localhost machine.
Using php.ini:auto_prepend_file = C:/public_html/debug/auto_prepend.php
auto_append_file = C:/public_html/debug/auto_append.php
Using .htaccess:
php_value auto_prepend_file C:/public_html/debug/auto_prepend.php
php_value auto_append_file C:/public_html/debug/auto_append.php
Debug console & ajax requests
If your scripts do some ajax requests, there might be some issues, because debug console might be displayed more than once, to avoid it, some simple modifications to auto_prepend.php & auto_append.php might be required. For example in your ajax scripts define some constant:
define('AJAX_REQUEST', 1);
And in auto_append.php:
debug_stop();
if (!(defined('AJAX_REQUEST') && AJAX_REQUEST)) {
echo debug_console();
}
But that still leaves some issues, because debug_start() has been called, and xdebug-trace data file will be overwritten, so when you click "xdebug-trace" popup you will see the trace of one of ajax requests, and not the original base-request. To solve this issue completely, you will have to copy the code from auto_*.php files into your projects index.php controller (or something) and detect ajax requests and disable debugging for such requests.
If you're using debug console through php.ini, you might want to enable/disable it for custom sites/urls, you will have to write a code like this in auto_prepend.php, auto_append.php:
auto_prepend.php:define('ENABLE_DEBUG', in_array($_SERVER['SERVER_NAME'], array('test.dev', 'www.test.dev', 'localhost')));
if (ENABLE_DEBUG) {
require ...
define ...
...
debug_start();
}
auto_append.php:
if (ENABLE_DEBUG) {
debug_stop();
echo debug_console();
}
Possible problems when sending ETags / caching content
A strange behavior might appear (starting/stopping xdebug session might not work) if you're sending ETag headers and including auto_prepend.php through php.ini. It happens because debug console html is sent after the script execution, so the content is different then the ETag suggests. Solution: implement including debug console in your scripts controller or disable sending etags on localhost by using for example such condition: if ('127.0.0.1' == $_SERVER['SERVER_ADDR'] && '127.0.0.1' == $_SERVER['REMOTE_ADDR']) { return; // do not send etag }
Example 2: debug errors
Input
<?php
require './lib/debug.php';
function test($a, $b)
{
echo $asd;
}
test(10, 'abc');
?>
Output
Example 3: debug using debug() function
Input
<?php
require './lib/debug.php';
function test($args)
{
test_nested($args);
}
function test_nested($args)
{
debug($args);
// or: debug(get_defined_vars());
// or: debug();
}
test(array('id'=>123, 'str'=>'test'));
?>
Output
Example 4: debug using dump(), dump_tofile() functions
This function is a light version of debug(), with just basic features and a light interface.
Input
<?php
include_once './lib/dump.php';
function test5()
{
include './testdata/test0.php';
$test = array('int'=>1, 'float'=>2.0, 'float2'=>2.1);
dump($test, $_SERVER);
}
function test1() { test2(); }
function test2() { test3(); }
function test3() { test4(); }
function test4() { test5(); }
test1();
?>
Output
dump_tofile()
This function is useful while debugging when:
- you don't want to stop the script execution.
- you can't display data, because for example it is an ajax request.
- you want to debug in more than one place through the request.
Example: debug/test7-dump_tofile.php
Example 5: debug database queries
Note: before proceeding chmod /dev/data/ directory so it is writable.
Input
<?php
include './auto_prepend.php';
include './lib/db-mysql.php';
db_connect(array(
'host' => 'localhost',
'user' => 'root',
'pass' => 'toor',
'dbname' => 'test',
'charset' => 'latin2'
));
db_query('CREATE TABLE IF NOT EXISTS testdebug (id int PRIMARY KEY)');
db_query('DELETE FROM testdebug WHERE 1=1');
db_insert('testdebug', array('id'=>1));
db_insert('testdebug', array('id'=>2));
db_insert('testdebug', array('id'=>3));
$id1 = db_one('SELECT id FROM testdebug WHERE id = %id', array('id'=>1));
$row_id2 = db_row('SELECT * FROM testdebug WHERE id = %0', array(1));
$assoc = db_assoc('SELECT id, id FROM testdebug ORDER BY id');
include './auto_append.php';
?>
Output
Step1 - click "db-debug (10)" to open popup window
Step2 - db-debug popup window
Input - mysql error
<?php
require './auto_prepend.php';
include './lib/db-mysql.php';
db_connect(array(
'host' => 'localhost',
'user' => 'root',
'pass' => 'toor',
'dbname' => 'test',
'charset' => 'latin2'
));
function test()
{
db_query('CREATE TABLE asd (id int PRIMARYYYY KEY)');
}
test();
require './auto_append.php';
?>
Output - mysql error
Changelog
1.03
- Fix to dump(): function did not output, when called after a call to dump_tofile()
1.02
- New tool: lib/dump.php with dump() and dump_tofile() functions.
1.01
- changes in auto_prepend.php: invalid path to xdebug-trace script when including from different directory (running tests worked, but when including for example through php.ini, then paths were invalid), this also applies to db-debug script.
- problems when including debug console via php.ini: the console was displayed also in the xdebug trace popup window, so the original xdebug session was overwritten (console is now disabled for the scripts in /dev/ by checking name of the php file, so these files names cannot be changed: xdebug-trace.php, db-debug.php, db-debug-analyze.php)
- fixed short open tags in php files (scripts in /dev/ now are working when short_open_tag directive is off in php.ini)
- changes in lib/debug.php: possible E_NOTICE errors if you had global variables named $_db or $Db, but keys debug_time/debug_queries were missing in these arrays.