<?php /* * Online profiling dump - Written by Jani Taskinen <sniper@iki.fi> A.D. 2007 * * Usage: * * You can either have this file included by using the php.ini * directive "auto_prepend_file" or including it in your script. * * Passing XDEBUG_PROFILE in GET/POST/COOKIE enables the output. * * Example of download.php: <?php if (file_exists("/{$_GET['file']}")) { $filesize=filesize("/{$_GET['file']}"); $file=basename("/{$_GET['file']}"); // If you want to have always same filename uncomment this: // header("Content-Disposition: attachment; filename=\"cachegrind.out\""); header("Content-Type: application/x-kcachegrind"); header("Content-Length: {$filesize}"); passthru("cat /tmp/xdebug/{$file}",$err); } exit; ?> * * Example of php.ini options: * [xdebug] zend_extension_debug = ${extension_dir}"/xdebug.so" xdebug.profiler_enable = Off xdebug.profiler_enable_trigger = On xdebug.profiler_output_dir = /tmp/xdebug xdebug.profiler_append = On xdebug.profiler_aggregate = Off xdebug.profiler_output_name = %H.%S ; <HTTP_HOST>.<SESSION_ID> xdebug.extended_info = 1 * */ function xdebug_profiler_shutdown_cb() { $is_xmlhttprequest = (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest'); if (isset($_REQUEST['XDEBUG_PROFILE'])) { $used_memory = xdebug_memory_usage(); $sizename = array(" Bytes", " KB", " MB", " GB"); $used_memory = round($used_memory / pow(1024, ($i = floor(log($used_memory, 1024)))), 2) . $sizename[$i]; $elapsed_time = round(xdebug_time_index() * 1000, 3); $profile = xdebug_get_profiler_filename(); $profile_id = md5($profile); /* Show result box */ if (!$is_xmlhttprequest) // FIXME: How to provide profiler links without breaking possible json? { if ($profile === false) { $path = ini_get('xdebug.profiler_output_dir'); if ($path != '') { $reason = is_dir($path) ? 'Directory is not writeable' : (file_exists($path) ? "'{$path}' is not directory" : "'$path' does not exist"); $output = sprintf('Error: Could not create profile dump in %s<br />(Reason: %s)', $path, $reason); } else { $output = 'Error: xdebug.profiler_output_dir is not set'; } } else { $output = " <b>Page generated in</b> {$elapsed_time} ms <b>Used memory:</b> {$used_memory} <b>Profiler dump:</b> <a href='/download.php?file={$profile}'>{$profile}</a> "; if ($_REQUEST['XDEBUG_PROFILE'] == 'long') { $output.= shell_exec("/usr/bin/callgrind_annotate --inclusive=yes --tree=both $profile"); } } echo <<< DATA <div style="position: absolute; top: 0; z-index: 5000; border: dashed black 1px; background-color: #fff;" id="xdebug_profile_{$profile_id}"> <a href="#" style="font-size: 11px;" onclick="javascript: document.getElementById('xdebug_profile_{$profile_id}').style.display = 'none'; return false;">[close]</a> <pre style="padding: 5px;">{$output}</pre> <a href="#" style="font-size: 11px;" onclick="javascript: document.getElementById('xdebug_profile_{$profile_id}').style.display = 'none'; return false;">[close]</a> </div> DATA; } } /* Output box with toggles to enable/disable profiler and annotation */ if (!$is_xmlhttprequest) { $profiler = isset($_REQUEST['XDEBUG_PROFILE']) ? array ( 'enabled' => 1, 'checked' => 'checked="checked"', 'display' => 'inline', ) : array ( 'enabled' => 0, 'checked' => '', 'display' => 'none', ); $profiler['checked_annotate'] = isset($_REQUEST['XDEBUG_PROFILE']) && $_REQUEST['XDEBUG_PROFILE'] == 'long' ? 'checked="checked"' : ''; echo <<< DATA <!-- XDEBUG Dynamic Profiler --> <script type="text/javascript"> <!-- var xdebug_Profiler = {$profiler['enabled']}; function xdebug_setCookie(value) { if (value == '') document.cookie = "XDEBUG_PROFILE=; path=/; expires=Thu, 01-Jan-1970 00:00:01 GMT"; else document.cookie = "XDEBUG_PROFILE=" + value + "; path=/; expires=Fri, 01-Jan-2038 00:00:01 GMT"; } function xdebug_toggleProfiler(output) { var annotate = document.getElementById('xdebug_profiler_annotate'); if (xdebug_Profiler) { xdebug_setCookie(''); xdebug_Profiler = 0; annotate.style.display = 'none'; } else { xdebug_setCookie(output); xdebug_Profiler = 1; annotate.style.display = 'inline'; } return xdebug_Profiler; } // --> </script> <div style="padding: 5px; border: dashed black 1px; background-color: #fff; z-index: 1000; position: absolute; top: 0px; right: 5px; " id="xdebug_profile_enable_cookie"> <label for="xdebug_toggler" style="vertical-align: top">Toggle Profiler</label> <input id="xdebug_toggler" type="checkbox" onclick="this.checked = xdebug_toggleProfiler(this.value);" value="short" {$profiler['checked']} /> <div id="xdebug_profiler_annotate" style="display: {$profiler['display']}"> <label for="xdebug_annotate" style="vertical-align: top">Annotate</label> <input id="xdebug_annotate" type="checkbox" onclick="xdebug_setCookie((this.checked)?this.value:'short');" value="long" {$profiler['checked_annotate']} /> </div> </div> DATA; } } /* Register shutdown function */ if (PHP_SAPI != 'cli') { register_shutdown_function('xdebug_profiler_shutdown_cb'); }