PHP Classes

File: src/unreal4u/debugInfo.php

Recommend this page to a friend!
  Classes of Camilo Sperberg   Debug Info   src/unreal4u/debugInfo.php   Download  
File: src/unreal4u/debugInfo.php
Role: Class source
Content type: text/plain
Description: Class source
Class: Debug Info
Output information about variables and other data
Author: By
Last change: Update of src/unreal4u/debugInfo.php
Date: 6 months ago
Size: 15,805 bytes
 

Contents

Class file image Download
<?php namespace unreal4u; /** * Common used functions when debugging applications * * @package debugInfo * @author Camilo Sperberg - http://unreal4u.com/ * @version 2.0.0 */ class debugInfo { /** * Version of this class * @var string */ private $classVersion = '2.0.0'; /** * The format of the timestamp that will be printed, based on strftime * @link http://php.net/manual/en/function.strftime.php * @var string */ public static $timeFormat = '%F %T'; /** * Private array with all the recorded data * @var array */ private $data = array(); /** * With how many decimals we want to print * @var int */ public $decimals = 6; /** * Constructor, can also be used to immediatly record a time * * @param string $identifier */ public function __construct($identifier='') { if (!empty($identifier)) { $this->beginCounter($identifier); } } /** * Magic function * * @return string */ public function __toString() { if (PHP_SAPI == 'cli') { $eol = PHP_EOL; } else { $eol = '<br />'; } return basename(__FILE__).' v'.$this->classVersion.' by unreal4u - Camilo Sperberg - http://unreal4u.com/'.$eol; } /** * Returns the current date and time to be used in the debug functions * * @see self::$timeFormat * @return string */ private static function getDateStamp() { return '[' . strftime(self::$timeFormat) . '] '; } /** * Makes debugging a variable easier * * This function applies htmlentities so you can print whatever you want and display it nicely on-screen. It will * work nicely with CLI programs too formatting the output to differ a bit from the output made through HTML. * * @param mixed $a Whatever you want to print * @param bool $print Whether you should echo inmediatly or only return the string * @param string $message The message to print before the variable printing * @return string The formatted what-so-ever you wanted to print */ public static function debug($a=null, $print=true, $message='') { $output = true; $type = gettype($a); // Check what action to take depending on type of data switch($type) { // Overwrite variable with string to indicate clearly what type of data we're dealing with case 'NULL': $a = '(null)'; break; // Overwrite variable with string to indicate clearly what type of data we're dealing with case 'boolean': if ($a === true) { $a = '('.$type.') true'; } else { $a = '('.$type.') false'; } break; // Indicate also empty string case 'string': if ($a === '') { $a = "(empty string) ''"; } break; // In case we're printing out an array, check out what for types each component of that array is // @TODO Disabled for now, it produces a disastrous result when printing out nested arrays #case 'array': # $copyOriginalArray = $a; # $a = array(); # foreach($copyOriginalArray AS $index => $value) { # $a[$index] = self::debug($value, false, $message); # } # break; } if (PHP_SAPI != 'cli') { // If outputting to browser, escape the contents $output = $message . htmlentities(print_r($a, true)); } else { // If in CLI mode, always add current timestamp and don't escape htmlentities $output = self::getDateStamp() . $message . print_r($a, true) . PHP_EOL; } if ($print === true) { // If we aren't working in CLI mode, add <pre> and custom class name if (PHP_SAPI != 'cli') { $output = '<pre class="u4u-debug">' . $output . '</pre>'; } echo $output; } // Return the output return $output; } /** * This function will debug through FirePHP * * Two pre-requisites are needed for this function to work properly: * <ul> * <li>You need to install: Firefox + Firebug extension + FirePHP extension * <ul><li><a href="http://www.mozilla.org/en-US/firefox/all/">Firefox</a></li> * <li><a href="https://getfirebug.com/">Firebug extension</a></li> * <li><a href="https://addons.mozilla.org/en-US/firefox/addon/firephp/">FirePHP extension</a></li> * </ul> * </li> * <li>The initial setup requires enabling the Console and Net tabs within Firebug</li> * <li>FirePHP PHP classes: * <ul> * <li><strong>composer/packagist</strong> * <ul><li>Execute <code>composer.phar install</code> or <code>composer.phar update</code></li> * <li>You're good to go!</li></ul> * </li> * <li><strong>PEAR</strong> * <ul><li><code>wget http://pear.php.net/go-pear</code></li> * <li><code>php go-pear.php</code></li> * <li>Then you need to install FirePHPCore code: * <ul><li><code>pear channel-discover pear.firephp.org</code></li> * <li><code>pear install firephp/FirePHPCore</code></li> * <li>You <strong>MUST</strong> include the FirePHPCore class (manually) by yourself! * <ul><li><code>include_once('FirePHPCore/FirePHP.class.php');</code></li></ul> * </li> * </ul> * </li> * </ul> * </li> * </ul> * </li> * </ul> * * The result of the output will appear in the Console tab within Firebug. * * Usage is exactly the same as the debug() function within this same class. * * @throws Exception Will throw an exception if headers are already sent * @param mixed $a Whatever we want to print * @param boolean $print Whether to print immediatly or not. Ignored for this function * @param string $message What message to append to */ public static function debugFirePHP($a=null, $print=false, $message='') { if (!headers_sent()) { include_once('../vendor/autoload.php'); $firePHP = \FirePHP::getInstance(true); $firePHP->log($a, $message); } else { throw new \Exception('Headers already sent, can not send FirePHP\'s messages'); } return self::debug($a, false, $message); } /** * Prints a message in a file * * Don't use this function for intensive file writing because for each message it prints, it will use some expensive * system calls * * @param string $message What we want to print * @param string $filename The filename to which we want to print * @param string $directory The directory in which we want to save the file. Defaults to sys_get_temp_dir() * @return boolean Returns true if write was successfull, false otherwise */ public static function debugFile($message='', $filename='', $directory='') { $success = false; if (empty($filename)) { $filename = 'u4u-log'; } if (empty($directory)) { // Trailing slash always needed, check http://www.php.net/manual/en/function.sys-get-temp-dir.php#80690 $directory = realpath(sys_get_temp_dir()).'/'; } $filename = $directory.$filename; if (is_writable($filename)) { $success = file_put_contents( $filename, // Where to write self::debug($message, false) . PHP_EOL, // Write the message FILE_APPEND // Writing mode ); } // file_put_contents can return number of bytes written or false in case of error, convert to boolean if ($success !== false) { $success = true; } return $success; } /** * Throws an ErrorException * * @param int $errno * @param string $errstr * @param string $errfile * @param int $errline * @throws ErrorException */ public static function exceptionErrorHandler($errno=null, $errstr=null, $errfile=null, $errline=null) { // @TODO Do something with severity other than to pass just the errno throw new \ErrorException($errstr, $errno, $errno, $errfile, $errline); } /** * Sets the error handler to throw exceptions only */ public static function throwExceptions() { set_error_handler(get_class().'::exceptionErrorHandler'); } /** * Returns the exact time * * @return float Returns the exact time+microtime */ public static function getExactTime() { return microtime(true); } /** * Formats a unix timestamp to a more human readable format * * @link http://www.php.net/manual/en/function.date.php * * @param number $time The time that we want to print. Leave empty for current timestamp * @param string $format Any format accepted by date. Defaults to ISO8601 * @return string Returns an ISO8601 formatted string with the passed on date */ public static function convertTimestamp($time=0, $format=null) { if (empty($time)) { $time = time(); } else { $time = intval($time); } if (!is_string($format)) { $format = \DateTime::ISO8601; } $date = new \DateTime(); $date->setTimeZone(new \DateTimeZone(date_default_timezone_get())); $date->setTimestamp($time); return $date->format($format); } /** * Gets the current used memory footprint * * @param string $format Choose between "B" (bytes), "KB", "KiB", "MB", "MiB", "GB", "GiB". Defaults to "B" * @param boolean $printUnit Print the unit suffix. Defaults to "false" * @return int Returns the memory usage in the requested format */ public function getMemoryUsage($format='B', $printUnit=false) { return $this->formatNumber(memory_get_usage(), $format, $printUnit); } /** * Gets the peak memory usage * * @param string $format Choose between "B" (bytes), "KB", "KiB", "MB", "MiB", "GB", "GiB". Defaults to "B" * @param boolean $printUnit Print the unit suffix. Defaults to "false" * @return string Returns the peak memory usage in the requested format */ public function getPeakMemoryUsage($format='B', $printUnit=false) { return $this->formatNumber(memory_get_peak_usage(), $format, $printUnit); } /** * Formats a number according to the given format * * @param float $number Any number * @param string $format Choose between "B" (bytes), "KB", "KiB", "MB", "MiB", "GB", "GiB". Defaults to "B" * @param boolean $printUnit Print the unit suffix. Defaults to "false" * @return string Returns the value in the requested format */ protected function formatNumber($number, $format='B', $printUnit=false) { $multiplier = 1; $unit = 'B'; switch(strtolower($format)) { case 'kb': $multiplier = 1000; $unit = 'KB'; break; case 'kib': $multiplier = 1024; $unit = 'KiB'; break; case 'mb': $multiplier = 1000 * 1000; $unit = 'MB'; break; case 'mib': $multiplier = 1024 * 1024; $unit = 'MiB'; break; case 'gb': $multiplier = 1000 * 1000 * 1000; $unit = 'GB'; break; case 'gib': $multiplier = 1024 * 1024 * 1024; $unit = 'GiB'; break; } $output = (string)round($number / $multiplier); if ($printUnit === true) { $output .= $unit; } return $output; } /** * Starts a counter * * @param string $identifier The identifier of the data we want to return * @return boolean Returns always true */ public function beginCounter($identifier) { // First step: get the current exact time if (!empty($identifier)) { if (!is_array($identifier)) { $identifier = array($identifier); } foreach($identifier AS $id) { $this->data[$id] = array(); $this->data[$id]['startTime'] = self::getExactTime(); $this->data[$id]['startMemorySize'] = memory_get_usage(); $this->data[$id]['startMemoryPeakSize'] = memory_get_peak_usage(); } } return true; } /** * Ends a counter and returns the elapsed time between start and end * * @param string $identifier The identifier of the data we want to return * @return float Returns a float containing the difference between start and end time */ public function endCounter($identifier='') { // First step: get the current exact time $time = self::getExactTime(); if (!empty($this->data[$identifier]['endTime'])) { $totalTime = $this->data[$identifier]['endTime'] - $this->data[$identifier]['startTime']; } else if (array_key_exists($identifier, $this->data)) { $this->data[$identifier]['endTime'] = $time; $this->data[$identifier]['endMemorySize'] = memory_get_usage(); $this->data[$identifier]['endMemoryPeakSize'] = memory_get_peak_usage(); } return $this->getDiff($identifier, 'time'); } /** * Delivers the memory difference of a identifier * * @param string $identifier The identifier of the data we want to return * @param string $type Can be "time", "memory", "peakmemory" or "all". Defaults to "all" */ public function getDiff($identifier, $type='all') { $return = false; if (!empty($identifier) AND !empty($this->data[$identifier]['endMemorySize'])) { switch($type) { case 'time': $return = sprintf('%.'.$this->decimals.'f', $this->data[$identifier]['endTime'] - $this->data[$identifier]['startTime']); break; case 'memory': $return = $this->formatNumber($this->data[$identifier]['endMemorySize'] - $this->data[$identifier]['startMemorySize'], 'KiB', true); break; case 'peakmemory': $return = $this->formatNumber($this->data[$identifier]['endMemoryPeakSize'] - $this->data[$identifier]['startMemoryPeakSize'], 'KiB', true); break; case 'all': $return = array(); $return['time'] = $this->getDiff($identifier, 'time'); $return['memory'] = $this->getDiff($identifier, 'memory'); $return['peakmemory'] = $this->getDiff($identifier, 'peakmemory'); break; } } return $return; } } include ('auxiliar-functions.php');