Location: PHPKode > scripts > SimpleReflector for PHP > awbush-SimpleReflector-748357f/SimpleReflector.class.php
<?php

/**
 * An easy-to-use reflection class for exposing an object's identity so
 * problems can be debugged quickly.
 * 
 * It does correct null/true/false/empty string detection.  A string just gets
 * output directly, whereas objects will have their class interfaces exposed. 
 * Everything dumped to screen is correctly escaped for HTML output so the rest
 * of the page doesn't break.
 * 
 * The following information is displayed for objects:
 * 
 * - Class file/line location (especially useful when the same name class is defined multiple times in the filesystem)
 * - Methods in the class, including parameter names.
 * - Contents of the object (simple print_r that is HTML escaped)
 * 
 * Example Usage:
 * 
 * <code>
 * SimpleReflector::jam($object); // echo info to screen
 * $str = SimpleReflector::jam($object, true); // returns info as a string
 * SimpleReflector::jam($object, false, 'crazy object'); // echo info to screen with a custom title instead of "SimpleReflector"
 * </code>
 * 
 * For quicker use, consider adding a short function to your applications:
 * 
 * <code>
 * function jam() { $args = func_get_args(); call_user_func_array(array('SimpleReflector', 'jam'), $args); }
 * </code>
 * 
 * Then instead of typing `SimpleReflector::jam(...)` you can just type `jam(...)`.
 * 
 * @package default
 * @author Anthony Bush
 * @copyright Academic Superstore 2006-2008, FreeBSD (revised) licensed
 * @version 1.0 (2008-10-20) - First public release after 2 years of internal-only use.
 **/
class SimpleReflector
{
	/**
	 * Completely expose the contents of the given item in a way that makes it
	 * easy to find out more about that item.
	 * 
	 * It displays invisible characters (nulls, boolean, empty strings) and
	 * builds collapsable tables out of arrays and objects.
	 *
	 * @param mixed $var the object / variable to dump
	 * @param boolean $return set to true if you want it to return the output rather than echo it (just like print_r)
	 * @return mixed if $return is true, returns the output as string, otherwise it returns true.
	 * @author Anthony Bush
	 **/
	public static function jam($var, $return = false, $overrideTitle = '') {
		$html = '';
		if (is_array($var)) {
			$html .= self::jamObject($var, true, $overrideTitle);
		} else if (is_object($var)) {
			$html .= self::jamObject($var, true, $overrideTitle);
		} else {
			$html .= '<pre>';
			if (strlen($overrideTitle) > 0) {
				$html .= htmlentities($overrideTitle);
			} else {
				$html .= 'SimpleReflector';
			}
			$html .= ': ' . self::getVisual($var) . '</pre>';
		}
		
		if ($return) {
			return $html;
		} else {
			echo $html;
			return true;
		}
	}
	
	/**
	 * Shows where item is defined (if it's an object) dumps it's contents, and
	 * lists the public / private methods in a collapsable format.
	 * 
	 * @param mixed $var the object / variable to dump
	 * @param boolean $return set to true if you want it to return the output rather than echo it (just like print_r)
	 * @return mixed if $return is true, returns the output as string, otherwise it returns true.
	 * @author Anthony Bush
	 **/
	protected static function jamObject($var, $return = false, $overrideTitle = '') {
		$html  = '';
		static $num = 0;
		
		if (is_object($var))
		{
			
			$reflector = new ReflectionClass($var);
			
			$html .= self::getShowHideJavascript();
			
			$html .= '<div class="debug">';
			$html .= '<a class="title" href="javascript:void(showHide(\'superjam' . $num . '\'))">';
			if (strlen($overrideTitle) > 0) {
				$html .= htmlentities($overrideTitle);
			} else {
				$html .= 'SimpleReflector: ' . $reflector->getName();
			}
			$html .= '</a>';
			$html .= '<div id="superjam' . $num . '" class="superjam_results" style="display:none">';

			// Show where this class is defined:
			$html .= 'Definition: ' . $reflector->getFileName() . ':' . $reflector->getStartLine() . "<br />\n";
			
			// Get methods
			$methods = array(
				  'public' => array()
				, 'private' => array()
				, 'protected' => array()
			);
			foreach ($reflector->getMethods() as $method) {
				if ($method->isPrivate()) {
					$access = 'private';
				} elseif ($method->isProtected()) {
					$access = 'protected';
				} else {
					$access = 'public';
				}
				$methods[$access][$method->getName()] = $method;
			}
			foreach ($methods as $access => $accessMethods) {
				ksort($methods[$access]);
			}
			
			// Show methods
			ob_start();
			foreach ($methods as $access => $accessMethods) {
				if ( ! empty($accessMethods)) {
					echo '<a class="' . $access . '" href="javascript:void(showHide(\'superjam_' . $access . $num . '\'))">Show/Hide ' . ucwords($access) . ' Methods</a>' . "<br />\n";
					echo '<pre id="superjam_' . $access . $num . '" class="superjam_methods" style="display:none">';
					foreach ($accessMethods as $method) {
						$params = array();
						foreach ($method->getParameters() as $param) {
							$params[] = '<span class="methodParam">$' . $param->getName() . '</span>';
						}
						$paramNames = implode(', ', $params);
						printf(
							   '<div class="method ' . $access . '">'
							   . "%s%s%s "
							   . '<span class="methodName">'
							   . "%s</span>("
							   . $paramNames
							   . ');</div>'
							   , $method->isAbstract() ? ' abstract' : ''
							   , $method->isFinal() ? ' final' : ''
							   , $method->isStatic() ? ' static' : ''
							   , $method->getName()
							   );
					}
					echo '</pre>';
				}
			}
			$html .= ob_get_clean();
			
			
			// Show contents
			$html .= '<a class="superjam_contents" href="javascript:void(showHide(\'superjam_contents' . $num . '\'))">Show/Hide Contents</a>' . "<br />\n";
			$html .= '<pre id="superjam_contents' . $num . '" style="display:none">';
			$html .= htmlentities(print_r($var, true));
			$html .= '</pre>';
			
			$html .= '</div>'; // superjam . $num
			$html .= '</div>'; // debug
			
			$num++;
		}
		else if (is_array($var))
		{
			
			// Just show contents
			$html .= self::getShowHideJavascript();
			$html .= '<div class="debug" style="border: 1px solid #000; background: #fff">';
			$html .= '<a class="title" style="display: block; background: #ddd; padding: 5px; font-weight: bold;" href="javascript:void(showHide(\'superjam' . $num . '\'))">';
			if (strlen($overrideTitle) > 0) {
				$html .= htmlentities($overrideTitle);
			} else {
				$html .= 'SimpleReflector: PHP Array';
			}
			$html .= '</a>';
			$html .= '<pre id="superjam' . $num . '" style="display:none; padding: 5px">';
			$html .= htmlentities(print_r($var, true));
			$html .= '</pre>';
			$html .= '</div>'; // debug
			
			$num++;
		}
		
		if ($return) {
			return $html;
		} else {
			echo $html;
			return true;
		}
		
	}
	
	protected static function getAncestors($class) {
		$classes = array($class);
		while ($class = get_parent_class($class)) {
			$classes[] = $class;
		}
		return $classes;
	}
	
	protected static function getVisual($var) {
		if (is_null($var)) {
			return '[null]';
		} else if ($var === true) {
			return '[true]';
		} else if ($var === false) {
			return '[false]';
		} else if ($var === '') {
			return '[empty string]';
		} else if (is_array($var)) {
			return self::jamObject($var, true);
		} else if (is_object($var)) {
			return self::jamObject($var, true);
		} else {
			return htmlentities($var);
		}
	}
	
	/**
	 * Internal function for printing out style / javascript that makes the
	 * collapsing features work.
	 * 
	 * @return string
	 * @author Anthony Bush
	 **/
	protected static function getShowHideJavascript() {
		static $called = false;
		if ($called) {
			return;
		}
		$called = true;
		ob_start();
		?>
		<style type="text/css" media="screen">
		/* <![CDATA[ */
			.debug {
				border: 1px solid #000;
				background: #fff;
				color: #000;
			}
			.debug,
			.debug table td {
				text-align: left;
			}
			.debug table {
				margin: .5em 0;
			}
			.debug .title {
				display: block;
				background: #ddd;
				padding: 5px;
				font-weight: bold;
			}
			.debug a:link,
			.debug a:visited,
			.debug a:hover,
			.debug a:active {
				color: #0000A2;
				font-weight: bold;
			}
			.debug .superjam_methods {
				display: none;
			}
			.debug .superjam_results {
				display: none;
				padding: 5px;
			}
			.debug .methodName {
				color: #9D6F38;
			}
		/* ]]> */
		</style>
		<script type="text/javascript" language="javascript" charset="utf-8">
		// <![CDATA[
			function showHide(elementId) {
				e = document.getElementById(elementId);
				if (e.style.display == 'none') {
					e.style.display = 'block';
				} else {
					e.style.display = 'none';
				}
			}
		// ]]>
		</script>
		<?php
		return ob_get_clean();
	}	
}

?>
Return current item: SimpleReflector for PHP