<?php // Проверка if (! defined('BASE_DIR')) exit('Access denied'); /** * This source file is part of the AVE.cms. More information, * documentation and tutorials can be found at http://www.ave-cms.ru * * @package AVE.cms * @file system/helpers/debug.php * @author @ * @copyright 2007-2015 (c) AVE.cms * @link http://www.ave-cms.ru * @version 4.0 * @since $date$ * @license license GPL v.2 http://www.ave-cms.ru/license.txt */ class Debug { protected static $time = array(); protected static $memory = array(); public function __construct() { // } /** * Функция для вывода переменной (для отладки) * * @param mixed $var любая переменная * @param bool $exit * @param null $bg * @param bool $echo * * @return false|null|string|string[] */ public static function _echo($var, $exit = false, $_bg = null, $echo = true) { $code = ''; $backtrace = debug_backtrace(); $backtrace = $backtrace[0]; if (preg_match('/([^\(]*)\((.*)\)/i', $backtrace['file'])) { preg_match('/([^\(]*)\((.*)\)/i', $backtrace['file'], $match); $file = $match[1]; } $fh = fopen((isset($file) ? $file : $backtrace['file']), 'r'); $line = 0; while (++$line <= $backtrace['line']) $code = fgets($fh); fclose($fh); preg_match('/' . __FUNCTION__ . '\s*\((.*)\)\s*;/u', $code, $name); unset ($code, $backtrace); ob_start(); var_dump($var); $var_dump = ob_get_contents(); $var_dump = preg_replace('/=>(\s+|\s$)/', ' => ', $var_dump); $var_dump = htmlspecialchars($var_dump); $var_dump = preg_replace('/(=>)/', '<span style="color: #ff8c00;">$1</span>', $var_dump); ob_end_clean(); if (! empty($name)) { $fn_name = explode(',', $name[1]); $fn_name = array_shift($fn_name); } else $fn_name = 'EVAL'; if ($_bg) $bg = 'style="background: #' . $_bg . ';"'; else $bg = ''; $var_dump = ' <style> .debug_bg { margin: 20px; border: 1px solid #d9d9d9; background-color: #f1efef; border-radius: 5px; box-shadow: 0 0 3px rgba(0, 0, 0, 0.1); font-family: "Consolas", Verdana, Arial; font-size: 11px; } .debug_top { color: #ffffff; font-size: 15px; font-weight: bold; padding-left: 20px; padding-top: 10px; padding-bottom: 10px; text-shadow: 0 1px 1px rgba(0, 0, 0, 0.75); background-color: #43648c; background-repeat: repeat-x; border-bottom: 1px solid #ffffff; } .debug_box { margin: 10px; padding: 4px; background-color: #efeded; border: 1px solid #dedcdc; } </style> <div class="debug_bg"> <div class="debug_top" ' . $bg . '> var_dump(<strong>' . trim($fn_name) . '</strong>) </div> '.self::_trace().' <div class="debug_box"> <pre style="background:#f5f5f5; color: #000; margin: 0; padding: 5px; border: 0; font-size: 11px; font-family: Consolas, Verdana, Arial;">' . $var_dump . '</pre> </div> </div> '; if (! $echo) return $var_dump; echo $var_dump; if ($exit) exit; } /** * Функция для вывода переменной (для отладки) * * @param mixed $var любая переменная * @param bool $exit * @param null $bg * @param bool $echo * * @return null|string|string[] */ public static function _print($var, $exit = false, $_bg = null, $echo = true) { $code = ''; $backtrace = debug_backtrace(); $backtrace = $backtrace[0]; if (preg_match('/([^\(]*)\((.*)\)/i', $backtrace['file'])) { preg_match('/([^\(]*)\((.*)\)/i', $backtrace['file'], $match); $file = $match[1]; } $fh = fopen((isset($file) ? $file : $backtrace['file']), 'r'); $line = 0; while (++$line <= $backtrace['line']) $code = fgets($fh); fclose($fh); preg_match('/' . __FUNCTION__ . '\s*\((.*)\)\s*;/u', $code, $name); ob_start(); print_r($var); $var_dump = htmlspecialchars(ob_get_contents()); $var_dump = preg_replace('/(=>)/', '<span style="color: #FF8C00;">$1</span>', $var_dump); ob_end_clean(); if (! empty($name)) { $fn_name = explode(',', $name[1]); $fn_name = array_shift($fn_name); } else $fn_name = 'EVAL'; if ($_bg) $bg = 'style="background: #' . $_bg . ';"'; else $bg = ''; $var_dump = ' <style> .debug_bg { margin: 20px; border: 1px solid #d9d9d9; background-color: #f1efef; border-radius: 5px; box-shadow: 0 0 3px rgba(0, 0, 0, 0.1); font-family: "Consolas", Verdana, Arial; font-size: 11px; } .debug_top { color: #ffffff; font-size: 15px; font-weight: bold; padding-left: 20px; padding-top: 10px; padding-bottom: 10px; text-shadow: 0 1px 1px rgba(0, 0, 0, 0.75); background-color: #4e5665; background-repeat: repeat-x; border-bottom: 1px solid #ffffff; } .debug_box { margin: 10px; padding: 4px; background-color: #efeded; border: 1px solid #dedcdc; } </style> <div class="debug_bg"> <div class="debug_top" ' . $bg . '> print_r(<strong>' . trim($fn_name) . '</strong>) </div> '.self::_trace().' <div class="debug_box"> <pre style="background:#f5f5f5; color: #000; margin: 0; padding: 5px; border: 0; font-size: 11px; font-family: Consolas, Verdana, Arial;">' . $var_dump . '</pre> </div> </div> '; if (! $echo) return $var_dump; echo $var_dump; if ($exit) exit; } /** * Функция для вывода переменной (для экспорта) * * @param mixed $var любая переменная * @param bool $exit * @param null $bg * @param bool $echo * * @return string */ public static function _exp($var, $exit = false, $_bg = null, $echo = true) { $code = ''; $backtrace = debug_backtrace(); $backtrace = $backtrace[0]; if (preg_match('/([^\(]*)\((.*)\)/i', $backtrace['file'])) { preg_match('/([^\(]*)\((.*)\)/i', $backtrace['file'], $match); $file = $match[1]; } $fh = fopen((isset($file) ? $file : $backtrace['file']), 'r'); $line = 0; while (++$line <= $backtrace['line']) $code = fgets($fh); fclose($fh); preg_match('/' . __FUNCTION__ . '\s*\((.*)\)\s*;/u', $code, $name); ob_start(); var_export($var); if (! empty($name)) { $fn_name = explode(',', $name[1]); $fn_name = array_shift($fn_name); } else $fn_name = 'EVAL'; if ($_bg) $bg = 'style="background: #' . $_bg . ';"'; else $bg = ''; $var_export = htmlspecialchars(ob_get_contents()); $var_export = preg_replace('/(=>)/', '<span style="color: #FF8C00;">$1</span>', $var_export); ob_end_clean(); $var_dump = ' <style> .debug_bg { margin: 20px; border: 1px solid #d9d9d9; background-color: #f1efef; border-radius: 5px; box-shadow: 0 0 3px rgba(0, 0, 0, 0.1); font-family: "Consolas", Verdana, Arial; font-size: 11px; } .debug_top { color: #ffffff; font-size: 15px; font-weight: bold; padding-left: 20px; padding-top: 10px; padding-bottom: 10px; text-shadow: 0 1px 1px rgba(0, 0, 0, 0.75); background-color: #ccc; background-repeat: repeat-x; border-bottom: 1px solid #ffffff; } .debug_box { margin: 10px; padding: 4px; background-color: #efeded; border: 1px solid #dedcdc; } </style> <div class="debug_bg"> <div class="debug_top" ' . $bg . '> var_export(<strong>' . trim($fn_name) . '</strong>) </div> '.self::_trace().' <div class="debug_box"> <pre style="background:#f5f5f5; color: #000; margin: 0; padding: 5px; border: 0; font-size: 11px; font-family: Consolas, Verdana, Arial;">' . $var_export . '</pre> </div> </div> '; if (! $echo) return $var_dump; echo $var_dump; if ($exit) exit; } /** * Функция для вывода переменной (для отладки) * * @param mixed $var любая переменная * @param bool $exit true - остановливает дальнейшее выполнение скрипта, false - продолжает выполнять скрипт * @param null $bg * @param bool $echo * * @return false|string */ public static function _html($var, $exit = false, $_bg = null, $echo = true) { $code = ''; $backtrace = debug_backtrace(); $backtrace = $backtrace[0]; if (preg_match('/([^\(]*)\((.*)\)/i', $backtrace['file'])) { preg_match('/([^\(]*)\((.*)\)/i', $backtrace['file'], $match); $file = $match[1]; } $fh = fopen((isset($file) ? $file : $backtrace['file']), 'r'); $line = 0; while (++$line <= $backtrace['line']) $code = fgets($fh); fclose($fh); preg_match('/' . __FUNCTION__ . '\s*\((.*)\)\s*;/u', $code, $name); ob_start(); var_export($var); if (! empty($name)) { $fn_name = explode(',', $name[1]); $fn_name = array_shift($fn_name); } else $fn_name = 'EVAL'; if ($_bg) $bg = 'style="background: #' . $_bg . ';"'; else $bg = ''; $var_dump = ob_get_contents(); ob_end_clean(); $var_dump = ' <style> .debug_bg { margin: 20px; border: 1px solid #d9d9d9; background-color: #f1efef; border-radius: 5px; box-shadow: 0 0 3px rgba(0, 0, 0, 0.1); font-family: "Consolas", Verdana, Arial; font-size: 11px; } .debug_top { color: #ffffff; font-size: 15px; font-weight: bold; padding-left: 20px; padding-top: 10px; padding-bottom: 10px; text-shadow: 0 1px 1px rgba(0, 0, 0, 0.75); background-color: #43648c; background-repeat: repeat-x; border-bottom: 1px solid #ffffff; } .debug_box { margin: 10px; padding: 4px; background-color: #efeded; border: 1px solid #dedcdc; } </style> <div class="debug_bg"> <div class="debug_top" ' . $bg . '> var_export(<strong>' . trim($fn_name) . '</strong>) </div> '.self::_trace().' <div class="debug_box"> <pre style="background:#f5f5f5; color: #000; margin: 0; padding: 5px; border: 0; font-size: 11px; font-family: Consolas, Verdana, Arial;">' . htmlentities($var_dump, ENT_QUOTES) . '</pre> </div> </div> '; if (! $echo) return $var_dump; echo $var_dump; if ($exit) exit; } /** * Функция для записи переменной в файл (для отладки) * * @param mixed $var любая переменная * @param bool $exit true - остановливает дальнейшее выполнение скрипта, false - продолжает выполнять скрипт * @param null $bg * @param bool $append */ public static function _dump($var, $exit = false, $bg = null, $append = true) { $code = ''; $backtrace = debug_backtrace(); $backtrace = $backtrace[0]; if (preg_match('/([^\(]*)\((.*)\)/i', $backtrace['file'])) { $file = preg_match('/([^\(]*)\((.*)\)/i', $backtrace['file'], $match); $file = $match[1]; } $fh = fopen((isset($file) ? $file : $backtrace['file']), 'r'); $line = 0; while (++$line <= $backtrace['line']) $code = fgets($fh); fclose($fh); preg_match('/' . __FUNCTION__ . '\s*\((.*)\)\s*;/u', $code, $name); ob_start(); var_dump($var); $var_dump = ob_get_contents(); $var_dump = preg_replace('/=>(\s+|\s$)/', ' => ', $var_dump); $var_dump = htmlspecialchars($var_dump); $var_dump = preg_replace('/(=> )+([a-zA-Z]+\(\d+\))/', '$1<span style="color: #FF8C00;">$2</span>', $var_dump); ob_end_clean(); if (! empty($name)) { $fn_name = explode(',', $name[1]); $fn_name = array_shift($fn_name); } else $fn_name = 'EVAL'; if (! $bg) { $br = '2a5885'; $bg = '43648c'; } else { $br = $bg; } $var_dump = ' <style> .debug_bg { margin: 20px; border: 1px solid #d9d9d9; background-color: #f1efef; border-radius: 5px; box-shadow: 0px 0px 3px rgba(0, 0, 0, 0.1); font-family: Consolas, Verdana, Arial; font-size: 11px; } .debug_top { color: #ffffff; font-size: 15px; font-weight: bold; padding-left: 20px; padding-top: 10px; padding-bottom: 10px; text-shadow: 0 1px 1px rgba(0, 0, 0, 0.75); background-color: #'.$bg.'; background-repeat: repeat-x; border-bottom: 1px solid #ffffff; } .debug_box { margin: 10px; padding: 4px; background-color: #efeded; border: 1px solid #dedcdc; } </style> <div class="debug_bg"> <div class="debug_top"> var_dump(<strong>' . trim($fn_name) . '</strong>) </div> '.self::_trace().' <div class="debug_box"> <pre style="background:#f5f5f5; color: #000; margin: 0; padding: 5px; border: 0; font-size: 11px; font-family: Consolas, Verdana, Arial;">' . $var_dump . '</pre> </div> </div> '; if ($append) file_put_contents(BASE_DIR . '/debug.html', $var_dump, FILE_APPEND); else file_put_contents(BASE_DIR . '/debug.html', $var_dump); if ($exit) exit; } /** * Функция для трейсинга дебаггера * * @param * @return string */ public static function _trace() { $bt = debug_backtrace(); $trace = $bt[1]; $line = $trace['line']; $file = $trace['file']; //$function = $trace['function']; $class = (isset($bt[2]['class']) ? $bt[2]['class'] : 'None'); if (isset($bt[2]['class'])) $type = $bt[2]['type']; else $type = 'Unknow'; $function = isset($bt[2]['function']) ? $bt[2]['function'] : 'None'; return sprintf('<div class="debug_box">Class: <strong>%s</strong> | Type: <strong>%s</strong> | Function: <strong>%s</strong></div><div class="debug_box">File: <strong>%s</strong> line <strong>%s</strong></div>', $class, $type, $function, $file, $line); } /** * Функция отвечает за начало таймера * * @param string $name любая переменная (ключ массива) */ public static function startTime($name = '') { Debug::$time[$name] = microtime(true); } /** * Функция отвечает за окончание таймера * * @param string $name любая переменная (ключ массива) * * @return string */ public static function endTime($name = '') { if (isset(Debug::$time[$name])) return sprintf("%01.4f", microtime(true) - Debug::$time[$name]) . ' sec'; } /** * Функция отвечает за начало подсчета используеой памяти * * @param string $name любая переменная (ключ массива) */ public static function startMemory($name = '') { Debug::$memory[$name] = memory_get_usage(); } /** * Функция отвечает за окончание подсчета используемой памяти * * @param string $name любая переменная (ключ массива) * @return string */ public static function endMemory($name = '') { if (isset(Debug::$memory[$name])) return Debug::formatSize(memory_get_usage() - Debug::$memory[$name]); } /** * Форматированный вывод размера * * @param int $size размер * @return string нормированный размер с единицой измерения */ public static function formatSize($size) { if ($size >= 1073741824) $size = round($size / 1073741824 * 100) / 100 . ' Gb'; elseif ($size >= 1048576) $size = round($size / 1048576 * 100) / 100 . ' Mb'; elseif ($size >= 1024) $size = round($size / 1024 * 100) / 100 . ' Kb'; else $size = $size . ' b'; return $size; } /** * Форматированный вывод чисел * * @param int $number число * @param int $decimal * @param string $after * @param string $thousand * @return string */ public static function numFormat($number, $decimal = 0, $after = ',', $thousand= '.') { if ($number) return number_format($number, $decimal, $after, $thousand); return ''; } /** * @param $header * @param $body * @param $caller * @param bool $exit */ public static function _errorSql ($header, $body, $caller, $exit = false) { // } /** * Вывод статистики * * @param null $type * * @return int|null|string */ public static function getStatistic ($type = null) { global $AVE_DB; $stat = null; switch ($type) { case 'time': $stat = number_format(microtime_diff(START_MICROTIME, microtime()), 3, ',', ' '); break; case 'memory': $stat = Debug::formatSize(memory_get_usage() - START_MEMORY); break; case 'peak': $stat = Debug::formatSize(memory_get_peak_usage()); break; case 'sqlcount': $stat = $AVE_DB->DBProfilesGet('count'); break; case 'sqltrace': $stat = count($AVE_DB->_query_list); break; case 'sqltime': $stat = $AVE_DB->DBProfilesGet('time'); break; case 'get': $stat = self::_stat_get('get'); break; case 'post': $stat = self::_stat_get('post'); break; case 'request': $stat = self::_stat_get('request'); break; case 'session': $stat = self::_stat_get('session'); break; case 'server': $stat = self::_stat_get('server'); break; case 'globals': $stat = self::_stat_get('globals'); break; } return $stat; } /** * @param string $type * * @return false|null|string|string[] */ public static function _stat_get($type = 'get') { ob_start(); if ($type == 'get') var_dump($_GET); else if ($type == 'post') var_dump($_POST); else if ($type == 'request') var_dump($_REQUEST); else if ($type == 'session') var_dump($_SESSION); else if ($type == 'server') var_dump($_SERVER); else if ($type == 'globals') var_dump($GLOBALS); $stat = ob_get_contents(); $stat = preg_replace('/=>(\s+|\s$)/', ' => ', $stat); $stat = htmlspecialchars($stat); $stat = preg_replace('/(=>)/', '<span style="color: #FF8C00;">$1</span>', $stat); $stat = '<pre style="background:#f5f5f5; color: #000; margin: 0; padding: 5px; border: 0; font-size: 11px; font-family: Consolas, Verdana, Arial;">'. $stat .'</pre>'; ob_end_clean(); return $stat; } /** * @return string */ public static function displayInfo () { global $AVE_DB; $out = PHP_EOL; $out .= '<link rel="stylesheet" href="/lib/debug/debug.css" />'; $out .= PHP_EOL; $out .= '<script>window.jQuery || document.write(\'<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js">\x3C/script>\')</script>'; $out .= PHP_EOL; $out .= '<script src="/lib/debug/debug.js"></script>'; $out .= PHP_EOL; $out .= ' <div id="debug-panel"> <div class="debug-wrapper"> <div id="debug-panel-legend" class="legend"> <span>Debug console</span> <a id="debugArrowMinimize" class="debugArrow" href="javascript:void(0)" title="Minimize" onclick="javascript:appTabsHide()">×</a> <span> <a id="tabGeneral" href="javascript:void(\'General\')" onclick="javascript:appExpandTabs(\'auto\', \'General\')">General</a> <a id="tabParams" href="javascript:void(\'Params\')" onclick="javascript:appExpandTabs(\'auto\', \'Params\')">Params</a> <a id="tabGlobals" href="javascript:void(\'Globals\')" onclick="javascript:appExpandTabs(\'auto\', \'Globals\')">Globals</a> <a id="tabQueries" href="javascript:void(\'Queries\')" onclick="javascript:appExpandTabs(\'auto\', \'Queries\')">SQL Queries (' . self::getStatistic('sqlcount') . ')</a> <a id="tabSqlTrace" href="javascript:void(\'SqlTrace\')" onclick="javascript:appExpandTabs(\'auto\', \'SqlTrace\')">SQL Trace (' . self::getStatistic('sqltrace') . ')</a> </span> </div> '; $out .= PHP_EOL; $out .= '<div id="contentGeneral" class="items" style="display: none">' . PHP_EOL; $out .= 'Time generation: ' . self::getStatistic('time') . ' sec'; $out .= '<br>'; $out .= 'Memory usage: ' . self::getStatistic('memory'); $out .= '<br>'; $out .= 'Memory peak usage: ' . self::getStatistic('peak'); $out .= '<br>'; $out .= 'SQL Queries: ' . $AVE_DB->DBProfilesGet('count') . ' for ' . $AVE_DB->DBProfilesGet('time') . ' sec'; $out .= '</div>'; $out .= PHP_EOL; $out .= '<div id="contentParams" class="items" style="display: none">' . PHP_EOL; $out .= 'GET:'; $out .= self::getStatistic('get'); $out .= '<br>'; $out .= 'POST:'; $out .= self::getStatistic('post'); $out .= '<br>'; $out .= 'REQUEST:'; $out .= self::getStatistic('request'); $out .= '<br>'; $out .= 'SESSION:'; $out .= self::getStatistic('session'); $out .= '<br>'; $out .= 'SERVER:'; $out .= self::getStatistic('server'); $out .= '</div>'; $out .= PHP_EOL; $out .= '<div id="contentGlobals" class="items" style="display: none">' . PHP_EOL; $out .= self::getStatistic('globals'); $out .= '</div>'; $out .= PHP_EOL; $out .= '<div id="contentQueries" class="items" style="display: none">' . PHP_EOL; $out .= $AVE_DB->DBProfilesGet('list'); $out .= '</div>'; $out .= PHP_EOL; $out .= '<div id="contentSqlTrace" class="items" style="display: none">' . PHP_EOL; $out .= $AVE_DB->showAllQueries(); $out .= '</div>'; $out .= PHP_EOL; $out .= '</div>'; return $out; } } ?>