Location: PHPKode > scripts > MicroTime Profiler > microtime-profiler/profiler.class.php
<?php 

/**
* This file contains the profiler class that allows to profile the performances of the PHP scripts.
* It allows to export the profile report in CSV and XML format.
*
* @package profiler
*/

/**
* PROFILE_FILE_TYPE_CSV Constant
*
* It's used in the {@link profiler::profiler()} class to specify which kind of out file will be produced
* @see profiler::profiler()
*/
define ('PROFILE_FILE_TYPE_CSV', 0);
/**
* PROFILE_FILE_TYPE_XML Constant
*
* It's used in the {@link profiler::profiler()} class to specify which kind of out file will be produced
* @see profiler::profiler()
*/
define ('PROFILE_FILE_TYPE_XML', 1);

/**
* PROFILE_CONFIG_PERCENT_DECIMAL Constant
*
* Here you can specify the number of decimal to be used in the elasped time percentage.
*/
define ('PROFILE_CONFIG_PERCENT_DECIMAL', 4);

/**
* PROFILE_LOCALIZE_DECIMAL_POINT Constant
*
* Here you can specify yor decimal separator, usefull for a correct CSV exportation.
*/
define ('PROFILE_LOCALIZE_DECIMAL_POINT', ',');

/**
* PROFILE_LOCALIZE_THOUSAND_SEPARATOR Constant
*
* Here you can specify yor thousand separator, usefull for a correct CSV exportation.
*/
define ('PROFILE_LOCALIZE_THOUSAND_SEPARATOR', '');

/**
* profiler class
*
* This class allows to profile your script performances.
*
* @package profiler
* @author Setec Astronomy
* @version 1.0
* @abstract Profile your PHP scripts
* @copyright 2004
* @example example.php An example of this class usage
*/

class profiler {

	/**
 	* @access private
	*/
	var $profiles = array ();
	/**
 	* @access private
	*/
	var $filename = array ();
	/**
 	* @access private
	*/
	var $file_type = array ();

	/**
	* Default constructor
	*
	* This is the default constructor of profiler class.
	*<code>
	*require_once (dirname (__FILE__) . '/profiler.class.php');
	*$profiler = new profiler ('test.csv', PROFILE_FILE_TYPE_CSV);
	*declare (ticks=1);
	*
	*Your code goes here!
	* 
	*</code>
	*/
	// public function profiler () {
	function profiler ($filename, $file_type = PROFILE_FILE_TYPE_TXT) {
		$this->profiles = array ();
		$this->filename = $filename;
		$this->file_type = $file_type;
		
		register_shutdown_function (array (&$this, 'saveProfiles')); 
		register_tick_function (array (&$this, 'handleTicks')); 
	}

	/**
 	* @access private
	*/
	// private function safe_set (&$var_true, $var_false = '')
	function safe_set (&$var_true, $var_false = '') {
		if (!isset ($var_true)) { 
			$var_true = $var_false; 
		}
		return $var_true;
	}
	
	/**
 	* @access private
	*/
	// private file_put_contents ($filename, $content) {
	function file_put_contents ($filename, $content) {
		if (is_dir (dirname ($filename))) {
			if (function_exists ('file_put_contents')) {
				return file_put_contents ($filename, $content);
			} else {
			   $fd = fopen ($filename, "wb");
			   $return = fwrite ($fd, $content);
			   fclose ($fd);
			   return $return;
			}
		} 
		return false;
	}		

	/**
 	* @access private
	*/
	// private function getMicrotime () { 
	function getMicrotime () { 
		list ($usec, $sec) = explode (' ', microtime ()); 
		return ((float)$usec + (float)$sec); 
	} 

	/**
 	* @access private
	*/
	// private function handleTicks () { 
	function handleTicks () {
		$debug = debug_backtrace ();
		if (isset ($debug[1])) {
			$last = $debug[1];
			$code_line = '';
			if (isset ($last['file']) && isset ($last['line'])) {
				$lines = file ($last['file']);
				if (isset ($lines[$last['line'] - 1])) {
					$code_line = ($lines[$last['line'] - 1]);
				} else {
					$code_line = 'EOF';
				}
			}
			$now = $this->getMicrotime ();
			$last['microtime'] =  sprintf('%.16f', $now);
			$last['elasped'] =  sprintf('%.16f', 0);
			$last['code'] =  trim ($code_line);
			if ($last['function'] == 'unknown') {
				$last['function'] = '';
			}
			$this->profiles[] = $last;
		}
	} 
	
	/**
 	* @access private
	*/
	// private function saveProfiles () { 
	function saveProfiles () {
		unregister_tick_function (array (&$this, 'handleTicks'));
		@array_shift ($this->profiles); // shift "register_tick_function (array (&$this, 'handleTicks'));"
		@array_shift ($this->profiles); // shift first "declare (ticks=1);"
		@array_shift ($this->profiles); // shift second "declare (ticks=1);"
		$now = $this->getMicrotime ();
		$output = '';
		$count = count ($this->profiles);
		if ($count > 0) {
			$this->safe_set ($this->profiles[$count - 1]['microtime']);	
			$this->safe_set ($this->profiles[0]['microtime']);	
			$total_elasped = sprintf ('%.16f', $this->profiles[$count - 1]['microtime'] - $this->profiles[0]['microtime']);
			if ($total_elasped > 0) {	
				
				switch ($this->file_type) {
					case PROFILE_FILE_TYPE_CSV:
						$output .= '"Row";"FileName";"Line";"Function";"Microtime";"Elasped";"Code";"Percentage"' . "\r\n"; 
						break; 
					case PROFILE_FILE_TYPE_XML:
						$output .= '<?xml version="1.0" encoding="iso-8859-1" ?' .'>' . "\r\n"; 
						$output .= "<profiler>\r\n"; 
						$output .= "\t<profiles>\r\n"; 
						break; 
				}

				for ($i = 0; $i < $count; $i ++) {
					$this->safe_set ($this->profiles[$i]['file']);	
					$this->safe_set ($this->profiles[$i]['line']);	
					$this->safe_set ($this->profiles[$i]['function']);	
					$this->safe_set ($this->profiles[$i]['microtime']);	
					$this->safe_set ($this->profiles[$i]['code']);
					$this->safe_set ($this->profiles[$i]['elasped'], 0);	
					
					if ($i == $count - 1) {
						$this->profiles[$i]['elasped'] = sprintf ('%.16f', $now - $this->profiles[$i]['microtime']);
					} else {
						$this->profiles[$i]['elasped'] = sprintf ('%.16f', $this->profiles[$i + 1]['microtime'] - $this->profiles[$i]['microtime']);
					}
					
					$this->profiles[$i]['elasped_percent'] = (100 * $this->profiles[$i]['elasped']) / $total_elasped;

					$elasped_percent = number_format ($this->profiles[$i]['elasped_percent'], PROFILE_CONFIG_PERCENT_DECIMAL, PROFILE_LOCALIZE_DECIMAL_POINT, PROFILE_LOCALIZE_THOUSAND_SEPARATOR) . ' %';
					$elasped = number_format ($this->profiles[$i]['elasped'], 16, PROFILE_LOCALIZE_DECIMAL_POINT, PROFILE_LOCALIZE_THOUSAND_SEPARATOR);
					$microtime = number_format ($this->profiles[$i]['microtime'], 16, PROFILE_LOCALIZE_DECIMAL_POINT, PROFILE_LOCALIZE_THOUSAND_SEPARATOR);
					$code = str_replace ('"', '""', $this->profiles[$i]['code']);

					switch ($this->file_type) {
						case PROFILE_FILE_TYPE_CSV:
							$output .= '"' . $i . '";"' . $this->profiles[$i]['file'] . '";"' . $this->profiles[$i]['line'] . '";"' .
								       $this->profiles[$i]['function'] . '";"' . $microtime . '";"' . 
									   $elasped . '";"' . $code . '";"' . 
									   $elasped_percent . '"' . "\r\n"; 
							break; 
						case PROFILE_FILE_TYPE_XML:
							$output .= "\t\t<profile id='" . $i . "'>\r\n"; 
							$output .= "\t\t\t<file>" .  htmlentities ($this->profiles[$i]['file']) . "</file>\r\n"; 
							$output .= "\t\t\t<line>" . $this->profiles[$i]['line'] . "</line>\r\n"; 
							$output .= "\t\t\t<function>" .  $this->profiles[$i]['function'] . "</function>\r\n"; 
							$output .= "\t\t\t<microtime>" . $microtime . "</microtime>\r\n"; 
							$output .= "\t\t\t<elasped>" . $elasped . "</elasped>\r\n"; 
							$output .= "\t\t\t<code>" .  htmlentities ($this->profiles[$i]['code']) . "</code>\r\n"; 
							$output .= "\t\t\t<elasped_percent>" . $elasped_percent . "</elasped_percent>\r\n"; 
							$output .= "\t\t</profile>\r\n"; 
							break; 
					}
				}
				switch ($this->file_type) {
					case PROFILE_FILE_TYPE_CSV:
						break; 
					case PROFILE_FILE_TYPE_XML:
						$output .= "\t</profiles>\r\n"; 
						$output .= "</profiler>\r\n"; 
						break; 
				}			
			}
		}
		$this->file_put_contents ($this->filename, $output);
	}
}

?>
Return current item: MicroTime Profiler