Skip to content

Instantly share code, notes, and snippets.

@oranblackwell
Created December 1, 2014 16:42
Show Gist options
  • Save oranblackwell/8ee78c36d7bccf523682 to your computer and use it in GitHub Desktop.
Save oranblackwell/8ee78c36d7bccf523682 to your computer and use it in GitHub Desktop.
For Daniel
<?php
if ( !function_exists ( 'debug' ) ) {
/**
* @author Oran Blackwell
* @version 3.6.1
* Change log:
* 3.6.1 - inelegantly added var_dump to is_object()
* 3.6.0 - Added DEFINE_ declaration for check_mysql_errors & mysql_query_log
* - Added internal Repo hosting IPs to allowed array (O2)
* 3.5.1 - str_replace "\t" in $args for string
* 3.5.0 - Added mysql_query_log() - no return value yet, ie. insert_id or error
* 3.4.0 - Added the BASIC debug_log_query() // needs work
* 3.3.2 - Updated <br> to <br />
* 3.3.1 - Added in always ouput query to debug_mysql_query()
* 3.3.0 - Added debug_mysql_query()
* 3.2.0 - Added debug_allowed_IP() As it was well over due
* 3.1.0 - Refactored debug_exit()
* 3.0.6 - Added true/false arg to debug_exit()
* 3.0.5 - Added debug_getuserip() to deal with Sungard's Loadbalancer handling of $_SERVER['REMOTE_ADDR']
* 3.0.4 - Added debug_exit() with simple $_GET['secret']
* 3.0.3 - Converted debug_log from appending data top PREpending data.
* 3.0.2 - Added debug_log() - I just wrote to a simple HTML file for now.
* 3.0.1 - Added in debug_function_declaration(), Update IPs and Email Address
* 2.0.4 - Merged a couple of similar versions that slipped through version control
* 2.0.3 - Added if (function_exists('date_default_timezone_set')) for php < 5.2
* 2.0.2 - Added $doc_root declaration to debug_mail
* 2.0.1 - Added in the $indenter for space restricted display
* 2.0.0 - Completely rewritten
* @~todo elegantly rewrite version 3.6.1
* @~todo re-write as OOP
* @~todo convert mysql to PDO
*/
/* Since PHP 5.1.0 using date_default_timezone_set() prevents:
* Warning: date() [function.date]: It is not safe to rely on the system's timezone settings.*/
if ( function_exists ( 'date_default_timezone_set' ) ) {
date_default_timezone_set ( "Europe/Dublin" );
}
function DEFINE_debug_allowed_IP() {
/**
* Simple function which maintains the list of allowed IPs for this set of debug functions
*
* @param bool|string $ip optional
*
* @return boolean TRUE | FALSE
*/
function debug_allowed_IP( $ip = false ) {
if ( $ip == false ) {
$ip = $_SERVER['REMOTE_ADDR'];
}
$allowedIPs = array (
"172.27.103.70",
"::1",
"127.0.0.1"
);
if ( in_array ( $ip, $allowedIPs ) ) {
return true;
}
return false;
}
}
function DEFINE_debug() {
/**
* Recursive Function which attempts to parse anything passed to it and return the formated details
* @since debug version 1.0.0
*
* @param mixed $args mandatory
* @param string $title optional
* @param boolean $toOutput optional default TRUE - Should the result be echod or returned
* @param mixed $isDebugMail optional default FALSE - debug_mail() has slightly exceptional behaviour
* @param mixed $indent optional default NULL - ability to modify the indentation
*
* @return string $toReturn
*/
function debug( $args, $title = '', $toOutput = true, $isDebugMail = false, $indent = null ) {
if ( debug_allowed_IP ( debug_getuserip () ) || $isDebugMail == true ) {
$indenter = " "; //$indenter = "\t";
$recursive_indent = "<span style='color:#AAAAAA;'>:</span>$indenter";
$doc_root = str_replace ( '\\', '/', $_SERVER['DOCUMENT_ROOT'] );
$backtrace = debug_backtrace ();
$line = htmlspecialchars ( $backtrace[0]['line'] );
$file = htmlspecialchars ( str_replace ( array ( '\\', $doc_root ), array ( '/', '' ), $backtrace[0]['file'] ) );
$class = !empty( $backtrace[1]['class'] ) ? htmlspecialchars ( $backtrace[1]['class'] ).'::' : '';
$function = !empty( $backtrace[1]['function'] ) ? htmlspecialchars ( $backtrace[1]['function'] ).'() '
: '';
$output = '<strong>'.$class.$function.' =&gt; '.$file.' #'.$line."</strong>\r\n";
$toReturn = '';
if ( is_object ( $args ) ) {
$type = get_class ( $args );
$toReturn .= $indent.$title.' <span style="color:#666">'.$type.'</span><br />'.$indent.'(<br />';
foreach ( $args as $name => $value ) {
$toReturn .= debug ( $value, $name, false, true, $indent.$recursive_indent );
}
ob_start ();
var_dump ( $args );
$toReturn .= ob_get_clean ();
$toReturn .= $indent.')<br />';
} elseif ( is_array ( $args ) ) {
$count = count ( $args );
$type = 'Array';
$toReturn .= $indent.$title.' = <span style="color:#666">'.$type.' ('.$count.')</span><br />'.$indent.'(<br />';
$keys = array_keys ( $args );
if ( array_keys ( $args ) == range ( 0, count ( $args ) ) ) {
$isAssoc = false;
} else {
$isAssoc = true;
}
foreach ( $keys as $name ) {
$value = $args[$name];
$toReturn .= debug (
$value,
( $isAssoc == true ? '['.$name.']' : '---'.$name ),
false,
true,
$indent.$recursive_indent
);
}
$toReturn .= $indent.')<br />';
} elseif ( is_string ( $args ) ) {
$args = str_replace ( "\t", " ", $args );
$type = 'String';
$type_color = '<span style="color:#008000">';
$toReturn .= $indent.$title.' = <span style="color:#666">'.$type.'('.strlen (
$args
).')</span> '
.$type_color.htmlentities ( $args ).'</span><br />';
} elseif ( is_int ( $args ) ) {
$type = 'Integer';
$type_color = '<span style="color:red">';
$toReturn .= $indent.$title.' = <span style="color:#666">'.$type.'('.strlen (
$args
).')</span> '
.$type_color.htmlentities ( $args ).'</span><br />';
} elseif ( is_null ( $args ) ) {
$type = 'NULL';
$type_color = '<span style="color:#666">';
$toReturn .= $indent.$title.'= <span style="color:#666">'.$type.'('.strlen (
$args
).')</span>'
.$type_color.' -NULL-</span><br />';
} elseif ( is_bool ( $args ) ) {
$type = 'boolean';
$type_color = '<span style="color:#92008d">';
$toReturn .= $indent.$title.'= <span style="color:#666">'.$type.'('.strlen (
$args
).')</span>'
.$type_color.( $args == 1 ? 'TRUE' : 'FALSE' ).'</span><br />';
} elseif ( is_float ( $args ) ) {
$type = 'Float';
$type_color = '<span style="color:#0099c5">';
$toReturn .= $indent.$title.' = <span style="color:#666">'.$type.'('.strlen (
$args
).')</span> '
.$type_color.htmlentities ( $args ).'</span><br />';
} elseif ( is_resource ( $args ) ) {
//for things like myConnection
$type = 'Resource';
$type_color = '<span style="color:#FF8000">';
ob_start ();
var_dump ( $args );
$output = ob_get_clean ();
$toReturn .= $indent.$title.' = <span style="color:#666">'.$type.' => '.$output.'</span> '
.$type_color.htmlentities ( $args ).'</span><br />';
}
if ( $toOutput === true ) {
echo '<div style="text-align:left; background-color:white; font: 100% monospace; color:black;">';
if ( $title != '' ) {
echo '<strong>'.$title.': </strong>';
}
echo '<pre>'.$output.$toReturn.'</pre></div>';
} else {
return $toReturn;
}
}
}
}
function DEFINE_debug_mail() {
function debug_mail( $args, $subject = 'debug' ) {
$doc_root = str_replace ( '\\', '/', $_SERVER['DOCUMENT_ROOT'] );
$backtrace = debug_backtrace ();
$line = htmlspecialchars ( $backtrace[0]['line'] );
$file = htmlspecialchars ( str_replace ( array ( '\\', $doc_root ), array ( '/', '' ), $backtrace[0]['file'] ) );
$class = !empty( $backtrace[1]['class'] ) ? htmlspecialchars ( $backtrace[1]['class'] ).'::' : '';
$function = !empty( $backtrace[1]['function'] ) ? htmlspecialchars ( $backtrace[1]['function'] ).'() ' : '';
$output = "<strong>$class$function =&gt; $file #$line</strong>\r\n";
$from = 'oran.blackwell@o2.com';
$headers = 'MIME-Version: 1.0'."\r\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1'."\r\n";
$headers .= 'From: '.$from."\r\n".
'Reply-To: '.$from."\r\n".
'X-Mailer: PHP/'.phpversion ();
mail (
"oran.blackwell@telefonica.com",
$subject.' '.date ( 'Y-m-d H:i:s' ),
$output.debug ( $args, $subject, false, true ),
$headers
);
}
}
/**
*
*/
function DEFINE_mysql_query_log() {
function mysql_query_log( $q, $message, $username, $file ) {
if ( !mysql_query ( $q ) ) {
$status = "ERROR";
$message = mysql_error ();
// array for storing errors querying database
global $mysql_query_log_errors;
$mysql_query_log_errors[] = array (
"file" => $file,
"error" => $message,
"when" => date ( 'Y/m/d H:i:s' ),
"query" => $q
);
$status = "ERROR (DISPLAYED)";
} else {
$status = "OK";
global $mysql_insert_id;
$mysql_insert_id = mysql_insert_id ();
}
$q = 'INSERT INTO query_log (username, status, file, query, message) VALUES
("'.$username.'", "'.$status.'", "'.$file.'", "'.mysql_real_escape_string (
$q
).'","'.$message.'")';
mysql_query ( $q );
}
}
function DEFINE_check_mysql_errors() {
function check_mysql_errors( &$errorContent = null ) {
$mysql_query_log_errors = $GLOBALS['mysql_query_log_errors'];
$count = count ( $mysql_query_log_errors );
// check if sql errors occured
if ( $count > 0 ) {
$errorContent .= '
<div id="errorsHolder">
<div id="errorsClicker"><a href="#">Error Log: Show / Hide </a></div>
<h1>WARNING: '.$count.' error(s) occured:</h1>
<div id="errorsHidable">
<table border="1" width=100%>';
foreach ( $mysql_query_log_errors AS $key => $value ) {
$errorContent .= '<tr><td colspan=2 class="error">
Error '.++$key.':</td></td>';
foreach ( $value AS $k => $v ) {
$errorContent .= '<tr>
<td class="errorHeader">';
if ( $k != 'query' ) {
$errorContent .= $k.'</td>
<td style="padding: 5px;">';
$errorContent .= nl2br ( $v );
} else {
$errorContent .= '<a href="#error_'.$key.'" class="showHide">'.$k.'</a></td>
<td class="hiddenError" id="error_'.$key.'">';
$errorContent .= nl2br ( $v );
}
$errorContent .= '</td>
</tr>';
}
}
$errorContent .= '
</table>
</div>
</div>';
return $errorContent;
}
}
}
function DEFINE_debug_mysql_query() {
function debug_mysql_query( $q ) {
//@todo why do I check the IP twice?
if ( mysql_error () && debug_allowed_IP ( debug_getuserip () ) ) {
debug ( array ( mysql_error (), $q ) );
} else {
debug ( $q );
}
}
}
function DEFINE_debug_function_declaration() {
function debug_function_declaration( $args ) {
if ( debug_allowed_IP ( debug_getuserip () ) ) {
$r = new ReflectionFunction( $args );
$file = $r->getFileName ();
$startLine = $r->getStartLine ();
debug ( array ( "Filename" => $file, "Start Line" => $startLine ) );
}
}
}
function DEFINE_debug_log_query() {
function debug_log_query( $q ) {
if ( mysql_error () ) {
debug_log ( array ( mysql_error (), $q ) );
} else {
debug_log ( $q );
}
}
}
function DEFINE_debug_log() {
function debug_log( $args, $subject = "debug_log" ) {
$doc_root = str_replace ( '\\', '/', $_SERVER['DOCUMENT_ROOT'] );
$backtrace = debug_backtrace ();
$line = htmlspecialchars ( $backtrace[0]['line'] );
$file = htmlspecialchars ( str_replace ( array ( '\\', $doc_root ), array ( '/', '' ), $backtrace[0]['file'] ) );
$class = !empty( $backtrace[1]['class'] ) ? htmlspecialchars ( $backtrace[1]['class'] ).'::' : '';
$function = !empty( $backtrace[1]['function'] ) ? htmlspecialchars ( $backtrace[1]['function'] ).'() ' : '';
$output = "<br /><strong>$class$function =&gt; $file #$line</strong><br />";
$logFile = "logs/log-".date ( "Y-m-d" ).".html";
$newContent = '<div class="likeXML"><ul><li class="collapseXML"><div>&lt;<span class="start-tag">'
.date ( "Y-m-d H:i:s" )
.'</span>&gt;</div>
'.debug ( $args, $subject, false, true ).'
<div>&lt;<span class="end-tag">'
.date ( "Y-m-d H:i:s" )
.'</span>&gt;</div></li></ul></div>
';
if ( is_writable ( $logFile ) ) {
if ( !$handle = fopen ( $logFile, 'a' ) ) {
/* To be handled: Cannot open file ($logFile)*/
}
fwrite ( $handle, $newContent );
/*Prepend as opposed to append the data
* @~todo Doesnt seem to work on windows 7 for some reason
*/
/*$len = strlen($newContent);
$final_len = filesize($file) + $len;
$cache_old = fread($handle, $len);
rewind($handle);
$i = 1;
while (ftell($handle) < $final_len) {
fwrite($handle, $newContent);
$newContent = $cache_old;
$cache_old = fread($handle, $len);
fseek($handle, $i * $len);
$i++;
}*/
fclose ( $handle );
} else {
/* @~todo Handle this, the file $logFile is not writable*/
}
}
}
function DEFINE_debug_exit() {
function debug_exit( $exitOthers = false ) {
if ( $_GET['secret'] == "2894124" && debug_allowed_IP ( debug_getuserip () ) ) {
if ( $exitOthers == false ) {
exit();
}
} elseif ( $exitOthers == true ) {
exit();
}
}
}
function DEFINE_debug_getuserip() {
function debug_getuserip() {
if ( isset( $_SERVER ) ) {
if ( isset( $_SERVER["HTTP_X_FORWARDED_FOR"] ) ) {
return $_SERVER["HTTP_X_FORWARDED_FOR"];
}
if ( isset( $_SERVER["HTTP_CLIENT_IP"] ) ) {
return $_SERVER["HTTP_CLIENT_IP"];
}
return $_SERVER["REMOTE_ADDR"];
}
if ( getenv ( 'HTTP_X_FORWARDED_FOR' ) ) {
return getenv ( 'HTTP_X_FORWARDED_FOR' );
}
if ( getenv ( 'HTTP_CLIENT_IP' ) ) {
return getenv ( 'HTTP_CLIENT_IP' );
}
return getenv ( 'REMOTE_ADDR' );
}
}
function DEFINE_debug_keepsecret() {
function debug_keepsecret( $arg = '?', $toOutput = true ) {
if ( isset( $_GET['secret'] ) && $_GET['secret'] != '' ) {
$toReturn = $arg.'secret='.$_GET['secret'];
if ( $toOutput == true ) {
echo $toReturn;
} else {
return $toReturn;
}
}
}
}
/** I use this method of declaration as some versions of PHP parse the script for
* defined functions/classes first
* So if(!function_exists('debug')) wasn't working on a couple of servers.
*/
DEFINE_debug ();
DEFINE_debug_mail ();
DEFINE_debug_mysql_query ();
DEFINE_debug_log_query ();
DEFINE_mysql_query_log ();
DEFINE_check_mysql_errors ();
DEFINE_debug_function_declaration ();
DEFINE_debug_log ();
DEFINE_debug_exit ();
DEFINE_debug_getuserip ();
DEFINE_debug_keepsecret ();
DEFINE_debug_allowed_ip ();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment