PHPDebug

Hoje conheci o script de debug do Richard Barros.
Um script simples e bem útil para um debug rápido do código PHP.

Acabei fazendo classe baseada em seu script, para exibir alguns valores de modo diferente.

A classe PHPDebug é apenas para um debug rápido, ela não fornece informações detalhadas sobre a execução.
Se procura algo mais profissional procure em http://www.xdebug.org/

O script original você pode encontrar no link http://www.richardbarros.com.br/blog/pessoal/um-script-de-debug-para-quem-esta-comecando-com-php

Vamos aos códigos…

Arquivo PHPDebug.php:

<?php
/**
 * Classe para debug simples
 *
 * Baseada no arquivo debug.php de Richard Barros <contato@richardbarros.com.br>
 *
 * @author Tarcísio Xavier Gruppi <txgruppi@gmail.com>
 * @version 0.3
 */
class PHPDebug {
	protected static $exclude = array(
		'var'=>array('GLOBALS','HTTP_POST_VARS','HTTP_GET_VARS','HTTP_SESSION_VARS','HTTP_COOKIE_VARS','HTTP_SERVER_VARS','HTTP_POST_FILES','_REQUEST','_ENV','HTTP_ENV_VARS','_SERVER'),
		'class'=>array(),
		'function'=>array()
	);

	protected static $include = array(
		'var'=>array(),
		'class'=>array(),
		'function'=>array()
	);

	protected static $export = array('var'=>true,'function'=>true,'class'=>true);

	protected static $time = null;

	protected static function getDebugValues($vars,$functions,$classes) {
		$exclude = self::$exclude;
		$include = self::$include;

		foreach ($include as $k=>$a) {
			foreach ($a as $v) {
				$i = array_search($v,$exclude[$k]);
				if ($i !== false) {
					unset($exclude[$i]);
				}
			}
		}

		foreach ($vars as $k => $v) {
			if (array_search($k,$exclude['var']) !== false) {
				unset($vars[$k]);
			}
		}
		foreach ($functions['user'] as $k=>$v) {
			if (array_search($v,$exclude['function']) !== false) {
				unset($functions[$k]);
			}
		}

		$selfName = get_class(new self());
		$selfIndex = array_search($selfName,$classes);

		array_splice($classes,0,$selfIndex+1);

		foreach ($classes as $k=>$v) {
			if (array_search($v,$exclude['class']) !== false) {
				unset($classes[$k]);
			}
		}

		unset($functions['internal']);

		return array('var'=>$vars,'function'=>$functions,'class'=>$classes);
	}

	public static function startTimer() {
		self::$time = microtime(true);
	}

	public function getTimer() {
		if (is_null(self::$time)) return false;
		return microtime(true)-self::$time;
	}

	public static function export($vars,$functions,$classes) {
		$values = self::getDebugValues($vars,$functions,$classes);
		$e = new Exception();

		$tableAttributes = 'style="background: #FFF; text-align: left; width: 97%; border-top: solid 10px #C54D3F; padding: 0px; margin: 35px 10px;" cellpadding="2" cellspacing="0"';
		$titleAttributes = 'colspan="2" style="background: #F6F3F0; border-bottom: solid 1px #CBA; padding-top: 10px; font: bold 10pt Georgia, Arial; color: #987;"';
		$tdAttributes = 'valign="top" style="font: 10pt Verdana; color: #008F7F; width: 20%;"';
		$tdValueAttributes = 'valign="top" style="font: 10pt Verdana; color: #404040;"';

		echo "<table $tableAttributes>";
		echo "<tr>";
		echo "<th colspan='2' $titleAttributes>Informações</th>";
		echo "</tr>";
		$line = 0;

		$color = $line++ % 2 == 0 ? '#FEFEFE' : '#F6F4F1';
		echo "<tr style='background:$color'>";
		echo "<td $tdAttributes><pre>Tempo de execução</pre></td>";
		echo "<td $tdValueAttributes><pre>";
		echo self::getTimer();
		echo " segundos</pre></td>";
		echo "</tr>";

		$color = $line++ % 2 == 0 ? '#FEFEFE' : '#F6F4F1';
		echo "<tr style='background:$color'>";
		echo "<td $tdAttributes><pre>Pilha</pre></td>";
		echo "<td $tdValueAttributes><pre>";
		echo $e->getTraceAsString();
		echo "</pre></td>";
		echo "</tr>";

		echo "</table>";

		if (self::$export['var'] && count($values['var'])) {
			echo "<table $tableAttributes>";
			echo "<tr>";
			echo "<th colspan='2' $titleAttributes>Variáveis</th>";
			echo "</tr>";
			$line = 0;
			foreach ($values['var'] as $k => $v) {
				$color = $line++ % 2 == 0 ? '#FEFEFE' : '#F6F4F1';
				echo "<tr style='background:$color'>";
				echo "<td $tdAttributes><pre>\$$k</pre></td>";
				echo "<td $tdValueAttributes><pre>";
				var_dump($v);
				echo "</pre></td>";
				echo "</tr>";
			}
			echo "</table>";
		}

		if (self::$export['function'] && count($values['function'])) {
			echo "<table $tableAttributes>";
			echo "<tr>";
			echo "<th colspan='2' $titleAttributes>Funções</th>";
			echo "</tr>";
			$line = 0;
			foreach ($values['function']['user'] as $v) {
				$color = $line++ % 2 == 0 ? '#FEFEFE' : '#FBF9F6';
				echo "<tr style='background:$color'>";
				echo "<td $tdAttributes><pre>$v</pre></td>";
				echo "<td $tdValueAttributes><pre>";
				Reflection::export(new ReflectionFunction($v));
				echo "</pre></td>";
				echo "</tr>";
			}
			echo "</table>";
		}

		if (self::$export['class'] && count($values['class'])) {
			echo "<table $tableAttributes>";
			echo "<tr>";
			echo "<th colspan='2' $titleAttributes>Classes</th>";
			echo "</tr>";
			$line = 0;
			foreach ($values['class'] as $v) {
				$color = $line++ % 2 == 0 ? '#FEFEFE' : '#FBF9F6';
				echo "<tr style='background:$color'>";
				echo "<td $tdAttributes><pre>$v</pre></td>";
				echo "<td $tdValueAttributes><pre>";
				Reflection::export(new ReflectionClass($v));
				echo "</pre></td>";
				echo "</tr>";
			}
			echo "</table>";
		}
	}

	public static function excludeValue($type,$name) {
		if (array_search($type,array('var','class','function')) === false) return false;
		if (array_search($name,self::$exclude[$type]) !== false) return true;
		self::$exclude[$type][] = $name;
		return true;
	}

	public static function includeValue($type,$name) {
		if (array_search($type,array('var','class','function')) === false) return false;
		if (array_search($name,self::$exclude[$type]) !== false) return true;
		self::$exclude[$type][] = $name;
		return true;
	}

	public static function setExport($type,$bool) {
		if (array_search($type,array('var','class','function')) === false) return false;
		self::$export[$type] = $bool;
		return true;
	}

	// Retorna string para eval
	public function __toString() {
		return get_class($this)."::export(get_defined_vars(),get_defined_functions(),get_declared_classes());";
	}
}
PHPDebug::startTimer();

No inicio do arquivo principal, geralmente o index.php, inclua o arquivo PHPDebug.php

<?php @include_once('PHPDebug.php'); ?>

Agora você pode executar o debug em qualquer parte do seu código com apenas um eval simples

<?php eval(new PHPDebug()) ?>

O código inserido no eval é executado no mesmo escopo onde está o eval, por isso uma chamada ao PHPDebug no final do index.php é diferente de uma chamada dentro de uma função.