Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [klasa] Debugger 1.0.0
Forum PHP.pl > Inne > Oceny
Bastion
Witam,

dzis przedstawiam klase class5.Debugger - w zalozeniu ma byc klasa wspolna wykorzystywana przez kolejne wersje klass z serii class5 oraz kolejnych . ze wzgledu ze beda z niej korzystac jednoczesnie obiekty jak i nie tylko klasa jest statyczna. Obsluguje takze prosty backtrace z ukrywanymi warstwami (rozwija sie poprzez [+]). uzywa sie tak :

Jesli chcemy bezposrenio na out :
Live demo : $errlevel 1$errno 1$errstr 'Something wrong'$skip =0)
{
$colors[1] = '#ff0000'$str[1] = 'Error';
$colors[2] = '#ee6600'$str[2] = 'Warning';
$colors[3] = '#00aa00'$str[3] = 'Notice';

$time_point = (self::get_microtime() - self::$init_time);

if (
self::$level 0)
{
$msg count(self::$events);
if (
self::$level >= $event['errlevel'])
{
self::$events[$msg] = array('time_point' => $time_point,
'caller' => $caller,
'errno' => $errno,
'errstr' => $errstr,
'errlevel' => $errlevel);
}

$out '<pre style="font-size: 12px; margin:0px;">';

if (
self::$backtrace)
{
$backtrace debug_backtrace();
$count count($backtrace);
$out.= '<span id="backtracep'.$msg.'" style="display:inline;" onclick="backtraces'.$msg.'.style.display=\'inline\'; backtracem'.$msg.'.style.display=\'inline\'; this.style.display=\'none\';">[+]</span';
$out.= '<span id="backtracem'.$msg.'" style="display:none;"  onclick="backtraces'.$msg.'.style.display=\'none\'; backtracep'.$msg.'.style.display=\'inline\'; this.style.display=\'none\';">[-]</span>';
}

$out.= ' ['.number_format($time_point,5).'s] :: ';
$out.= '<strong>'.$caller'</strong> :: ';
$out.= '<font color="'.$colors[$errlevel].'">'.$str[$errlevel].'</font> - ';
$out.= $errstr.' (errno #'.$errno.')<br />';

if (
self::$backtrace)
{
$out.= '<div id="backtraces'.$msg.'" style="display:none;">';
for (
$i 1$i <= ($count-$skip); $i++)
{
$line $backtrace[($count-$i)]['line'];
$file $backtrace[($count-$i)]['file'];
$func $backtrace[($count-$i)]['function'];
$class $backtrace[($count-$i)]['class'];
$type $backtrace[($count-$i)]['type'];
$args = ($func<>'add_event') ? $backtrace[($count-$i)]['args'] : array();
$pargs '';

$out.= 'Call <font color="#0000aa">'.$class.$type.$func.'(';
foreach (
$args as $arg)
{
if (!empty(
$pargs))
{
$pargs .= ', ';
}

switch (
gettype($arg))
{
case 
'integer':
case 
'double':
$pargs .= $arg;
break;
case 
'string':
$pargs .= '"'.htmlspecialchars(substr($arg016)).((strlen($arg) > 16) ? '...' '').'"';
break;
case 
'array':
$pargs .= 'Array('.count($arg).')';
break;
case 
'object':
$pargs .= 'Object('.get_class($arg).')';
break;
case 
'resource':
$pargs .= 'Resource('.strstr($arg'#').')';
break;
case 
'boolean':
$pargs .= $arg 'True' 'False';
break;
case 
'NULL':
$pargs .= 'Null';
break;
default:
$pargs .= 'Unknown';
}
}
$out.= $pargs.');</font> in file <font color="#009900">'.$file.'</font>, line '.$line.'<br />';
}
$out.= '<hr /></div>';
}
$out.= '</pre>';

self::$events[$msg]['out'] = $out;

if (
self::$messages)
{
print 
self::$events[$msg]['out'];
}
}

if (
$event['errlevel'] == && self::$halt_on_error)
{
die(
'terminated...');
}
}

public function __construct()
{
global 
$_inited_modules;

if (empty(
$_inited_modules[self::className]))
{
$_inited_modules[self::className] = array('version' => self::classVersion,
'relase' => self::classRelase,
'vendor' => self::classVendor,
'vendorURL' => self::classVendorURL,
'description' => self::classDescription,
'copies' => 1);
} else
{
$_inited_modules[self::className]['copies']++;
}

self::$init_time self::get_microtime();
}
}

$__debugger = new Debugger;

?>
ime 0;

static 
public $events = array();
static 
public $halt_on_error true;
static 
public $backtrace true;
static 
public $level 1;
static 
public $messages true;

static 
private function get_microtime()
{
list(
$usec$sec) = explode(" "microtime());
return ((float)
$usec + (float)$sec);
}

static 
public function add_event($caller 'Undefined'$errlevel 1$errno 1$errstr 'Something wrong'$skip =0)
{
$colors[1] = '#ff0000'$str[1] = 'Error';
$colors[2] = '#ee6600'$str[2] = 'Warning';
$colors[3] = '#00aa00'$str[3] = 'Notice';

$time_point = (self::get_microtime() - self::$init_time);

if (
self::$level 0)
{
$msg count(self::$events);
if (
self::$level >= $event['errlevel'])
{
self::$events[$msg] = array('time_point' => $time_point,
'caller' => $caller,
'errno' => $errno,
'errstr' => $errstr,
'errlevel' => $errlevel);
}

$out '<pre style="font-size: 12px; margin:0px;">';

if (
self::$backtrace)
{
$backtrace debug_backtrace();
$count count($backtrace);
$out.= '<span id="backtracep'.$msg.'" style="display:inline;" onclick="backtraces'.$msg.'.style.display=\'inline\'; backtracem'.$msg.'.style.display=\'inline\'; this.style.display=\'none\';">[+]</span';
$out.= '<span id="backtracem'.$msg.'" style="display:none;"  onclick="backtraces'.$msg.'.style.display=\'none\'; backtracep'.$msg.'.style.display=\'inline\'; this.style.display=\'none\';">[-]</span>';
}

$out.= ' ['.number_format($time_point,5).'s] :: ';
$out.= '<strong>'.$caller'</strong> :: ';
$out.= '<font color="'.$colors[$errlevel].'">'.$str[$errlevel].'</font> - ';
$out.= $errstr.' (errno #'.$errno.')<br />';

if (
self::$backtrace)
{
$out.= '<div id="backtraces'.$msg.'" style="display:none;">';
for (
$i 1$i <= ($count-$skip); $i++)
{
$line $backtrace[($count-$i)]['line'];
$file $backtrace[($count-$i)]['file'];
$func $backtrace[($count-$i)]['function'];
$class $backtrace[($count-$i)]['class'];
$type $backtrace[($count-$i)]['type'];
$args = ($func<>'add_event') ? $backtrace[($count-$i)]['args'] : array();
$pargs '';

$out.= 'Call <font color="#0000aa">'.$class.$type.$func.'(';
foreach (
$args as $arg)
{
if (!empty(
$pargs))
{
$pargs .= ', ';
}

switch (
gettype($arg))
{
case 
'integer':
case 
'double':
$pargs .= $arg;
break;
case 
'string':
$pargs .= '"'.htmlspecialchars(substr($arg016)).((strlen($arg) > 16) ? '...' '').'"';
break;
case 
'array':
$pargs .= 'Array('.count($arg).')';
break;
case 
'object':
$pargs .= 'Object('.get_class($arg).')';
break;
case 
'resource':
$pargs .= 'Resource('.strstr($arg'#').')';
break;
case 
'boolean':
$pargs .= $arg 'True' 'False';
break;
case 
'NULL':
$pargs .= 'Null';
break;
default:
$pargs .= 'Unknown';
}
}
$out.= $pargs.');</font> in file <font color="#009900">'.$file.'</font>, line '.$line.'<br />';
}
$out.= '<hr /></div>';
}
$out.= '</pre>';

self::$events[$msg]['out'] = $out;

if (
self::$messages)
{
print 
self::$events[$msg]['out'];
}
}

if (
$event['errlevel'] == && self::$halt_on_error)
{
die(
'terminated...');
}
}

public function __construct()
{
global 
$_inited_modules;

if (empty(
$_inited_modules[self::className]))
{
$_inited_modules[self::className] = array('version' => self::classVersion,
'relase' => self::classRelase,
'vendor' => self::classVendor,
'vendorURL' => self::classVendorURL,
'description' => self::classDescription,
'copies' => 1);
} else
{
$_inited_modules[self::className]['copies']++;
}

self::$init_time self::get_microtime();
}
}

$__debugger = new Debugger;

?>
splatch
Dobry pomysł ale niestety, w praktyce trudny do wykorzystania. Po pierwsze, nie zastąpi on w pełni debuggera takiego jak ma np. php Eclipse, gdzie krok po kroku można się poruszać pomiędzy breakpointami, gdzie od razu widać zmienne, jakie trafiły do funkcji oraz zrzut tablic superglobalnych.
Coś takiego jest bardzo trudne do uzyskania przy użyciu Twojej klasy i szczerze wątpie by mimo dobrych opini ktoś jej używał przy pisaniu. Mi np. o wiele wygodniej kliknać na marginesie i odpalić debuggera w moim IDE niż wpisywać kolejne linie kodu.
Przykład który podałeś nie sprawdzi się również w praktyce ponieważ na serwerze produkcyjnym nie będziesz chciał takiej informacji pokazywać ze względów bezpieczeństwa. Użytkownik w takiej sytuacji powinien dostać wiadomość, że operacja się nie powiodła a nie stack trace. Takie sytuacje powinno się załatwiać loggerami - w javie wielką popularnością cieszy się pakiet common.logging albo Log4J (powstały również porty do php). Logi odkładają się w jednym miejscu, gdy w gotowej aplikacji wystąpi błąd programista zagląda do logów i analizuje, diagnozuje przyczynę błędu. Oczywiście nie zawsze takie rozwiązanie jest dobre.
Nie wiadomo czym ta klasa ma być - czy kolejnym error handlerem czy czymś innym? Jako exception handler nie zda się, ponieważ po wykonaniu exception handlera php i tak kończy pracę. Kończąc - mimo dobrego wykonania - po prostu nie widzę zastosowania dla tej klasy.
Invision Power Board © 2001-2024 Invision Power Services, Inc.