<?php
error_reporting(E_ALL);
function hhb_var_dump() {
//<changelog>
//v5, fixed warnings on PHP < 5.0.2 (PHP_EOL not defined) (although we do not undefine("PHP_EOL") .. not sure how to do that :( ),
//also we can use xdebug_var_dump when available now.
//v4, now (tries to) tell you the source code that lead to the variables
//v3, HHB_VAR_DUMP_START and HHB_VAR_DUMP_END .
//v2, now compat with.. PHP5.0 + i think? tested down to 5.2.17 (previously only 5.4.0+ worked)
//</changelog>
//<settings>
if(!defined('PHP_EOL')){//for PHP <5.0.2
$we_defined_PHP_EOL=true;
define('PHP_EOL',"\n");
}
$debug_hhb_var_dump = false; //if true, may throw exceptions on errors..
$use_xdebug_var_dump=false;//try to use xdebug_var_dump (instead of var_dump) if available?
$fancy_sourcecode_analyze_setting = true; //false to disable the fancy source code analyze stuff.
//(it will fallback to making $fancy_sourcecode_analyze_setting=false, if it fail to analyze the code, anyway..)
$hhb_var_dump_prepend = 'HHB_VAR_DUMP_START'.PHP_EOL;
$hhb_var_dump_append = 'HHB_VAR_DUMP_END'.PHP_EOL;
//</settings>
$use_xdebug_var_dump=($use_xdebug_var_dump && is_callable("xdebug_var_dump"));
if(!defined("PHP_EOL")){//for PHP 5.0.2<=...
$we_defined_PHP_EOL=true;
define('PHP_EOL',"\n");
}
$argv = func_get_args();
$argc = count($argv, COUNT_NORMAL);
if (version_compare(PHP_VERSION, '5.4.0', '>=')) {
$bt = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
} else if (version_compare(PHP_VERSION, '5.3.6', '>=')) {
$bt = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
} else if (version_compare(PHP_VERSION, '5.2.5', '>=')) {
$bt = debug_backtrace(false);
} else {
$bt = debug_backtrace();
};
$fancy_sourcecode_analyze = $fancy_sourcecode_analyze_setting;
//later, $fancy_sourecode_analyze will be compared with $fancy_sourcecode_analyze_settings
//to determine if the reason was an error analyzing, or if it was disabled..
$bt = $bt[0];
//<analyzeSourceCode>
if ($fancy_sourcecode_analyze)
{
$argvSourceCode = array(0 => 'ignore [0]...');
try {
if (version_compare(PHP_VERSION, '5.2.2', '<')) {
throw new Exception("PHP version is <5.2.2 .. see token_get_all changelog..");
};
$xsource = file_get_contents($bt['file']);
if (empty($xsource)) {
throw new Exception('cant get the source of '.$bt['file']);
};
$xsource.= '<?php ignore_this_hhb_var_dump_workaround();'; //workaround, making sure that at least 1 token is an array, and has the $tok[2] >= line of hhb_var_dump
$xTokenArray = token_get_all($xsource);
//<trim$xTokenArray>
$tmpstr='';
$tmpUnsetKeyArray = array();
ForEach($xTokenArray as $xKey => $xToken) {
if (is_array($xToken)) {
$tmpstr = trim($xToken[1]);
if (empty($tmpstr) && $tmpstr!=='0'/*string("0") is considered "empty" -.-*/) {
$tmpUnsetKeyArray[] = $xKey;
continue;
};
switch ($xToken[0]) {
case T_COMMENT:
case T_DOC_COMMENT: //T_ML_COMMENT in PHP4 -.-
case T_INLINE_HTML:
{
$tmpUnsetKeyArray[] = $xKey;
continue;
};
default:
{
continue;
}
}
} else if (is_string($xToken)) {
$tmpstr = trim($xToken);
if (empty($tmpstr) && $tmpstr!=='0'/*string("0") is considered "empty" -.-*/) {
$tmpUnsetKeyArray[] = $xKey;
};
continue;
} else {
//should be unreachable..
//failed both is_array() and is_string() ???
throw new LogicException('Impossible! $xToken fails both is_array() and is_string() !! .. ');
};
};
ForEach($tmpUnsetKeyArray as $toUnset) {
unset($xTokenArray[$toUnset]);
};
$xTokenArray = array_values($xTokenArray); //fixing the keys..
//die(var_dump('die(var_dump(...)) in '.__FILE__.':'.__LINE__,'before:',count(token_get_all($xsource),COUNT_NORMAL),'after',count($xTokenArray,COUNT_NORMAL)));
unset($tmpstr,$xKey, $xToken, $toUnset, $tmpUnsetKeyArray);
//</trim$xTokenArray>
$firstInterestingLineTokenKey = -1;
$lastInterestingLineTokenKey = -1;
//<find$lastInterestingLineTokenKey>
ForEach($xTokenArray as $xKey => $xToken) {
if (!is_array($xToken) || !is_integer($xToken[2]) || $xToken[2] < $bt['line']) continue;
//die(var_dump('die(var_dump(...)) in '.__FILE__.':'.__LINE__,$xToken,token_name($xToken[0]),$xTokenArray));
$tmpkey = $xKey; //we don't got what we want yet..
while (true) {
if (!array_key_exists($tmpkey, $xTokenArray)) {
throw new Exception('1unable to find $lastInterestingLineTokenKey !');
};
if ($xTokenArray[$tmpkey] === ';') {
//var_dump(__LINE__.":SUCCESS WITH",$tmpkey,$xTokenArray[$tmpkey]);
$lastInterestingLineTokenKey = $tmpkey;
break;
}
//var_dump(__LINE__.":FAIL WITH ",$tmpkey,$xTokenArray[$tmpkey]);
//if $xTokenArray has >=PHP_INT_MAX keys, we don't want an infinite loop, do we? ;p
//i wonder how much memory that would require though.. over-engineering, err, time-wasting, ftw?
if ($tmpkey >= PHP_INT_MAX) {
throw new Exception('2unable to find $lastIntperestingLineTokenKey ! (PHP_INT_MAX reached without finding ";"...)');
};
++$tmpkey;
}
break;
};
if ($lastInterestingLineTokenKey <= -1) {
throw new Exception('3unable to find $lastInterestingLineTokenKey !');
};
unset($xKey,$xToken,$tmpkey);
//</find$lastInterestingLineTokenKey>
//<find$firstInterestingLineTokenKey>
//now work ourselves backwards from $lastInterestingLineTokenKey to the first token where $xTokenArray[$tmpi][1] == "hhb_var_dump"
//i doubt this is fool-proof but.. cant think of a better way (in userland, anyway) atm..
$tmpi = $lastInterestingLineTokenKey;
do {
if (array_key_exists($tmpi, $xTokenArray) && is_array($xTokenArray[$tmpi]) && array_key_exists(1, $xTokenArray[$tmpi]) && is_string($xTokenArray[$tmpi][1]) && strcasecmp($xTokenArray[$tmpi][1], $bt['function']) === 0) {
//var_dump(__LINE__."SUCCESS WITH",$tmpi,$xTokenArray[$tmpi]);
if (!array_key_exists($tmpi + 2, $xTokenArray)) { //+2 because [0] is (or should be) "hhb_var_dump" and [1] is (or should be) "("
throw new Exception('1unable to find the $firstInterestingLineTokenKey...');
};
$firstInterestingLineTokenKey = $tmpi + 2;
break; /**/
};
//var_dump(__LINE__."FAIL WITH ",$tmpi,$xTokenArray[$tmpi]);
--$tmpi;
} while (-1 < $tmpi);
//die(var_dump('die(var_dump(...)) in '.__FILE__.':'.__LINE__,$tmpi));
if ($firstInterestingLineTokenKey <= -1) {
throw new Exception('2unable to find the $firstInterestingLineTokenKey...');
};
unset($tmpi);
//Note: $lastInterestingLineTokeyKey is likely to contain more stuff than only the stuff we want..
//</find$firstInterestingLineTokenKey>
//<rebuildInterestingSourceCode>
//ok, now we have $firstInterestingLineTokenKey and $lastInterestingLineTokenKey....
$interestingTokensArray = array_slice($xTokenArray, $firstInterestingLineTokenKey, (($lastInterestingLineTokenKey - $firstInterestingLineTokenKey) + 1));
unset($addUntil, $tmpi, $tmpstr,$tmpi,$argvsourcestr, $tmpkey,$xTokenKey,$xToken);
$addUntil = array();
$tmpi = 0;
$tmpstr = "";
$tmpkey = "";
$argvsourcestr = "";
//$argvSourceCode[X]='source code..';
ForEach($interestingTokensArray as $xTokenKey => $xToken) {
if (is_array($xToken)) {
$tmpstr = $xToken[1];
//var_dump($xToken[1]);
} else if (is_string($xToken)) {
$tmpstr = $xToken;
//var_dump($xToken);
} else { /*should never reach this */
throw new LogicException('Impossible situation? $xToken fails is_array() and fails is_string() ...');
};
$argvsourcestr.= $tmpstr;
if ($xToken === '(') {
$addUntil[] = ')';
continue;
};
if ($xToken === ')') {
if (false === ($tmpkey = array_search(')', $addUntil, false))) {
$argvSourceCode[] = substr($argvsourcestr, 0, -1); //-1 is to strip the ")"
if (count($argvSourceCode, COUNT_NORMAL) - 1 === $argc) /*-1 because $argvSourceCode[0] is bullshit*/ {
break; /*We read em all! :D (.. i hope)*/
};
/*else... oh crap*/
throw new Exception('failed to read source code of (what i think is) argv['.count($argvSourceCode, COUNT_NORMAL).'] ! sorry..');
}
unset($addUntil[$tmpkey]);
continue;
}
if (empty($addUntil) && $xToken === ',') {
$argvSourceCode[] = substr($argvsourcestr, 0, -1); //-1 is to strip the comma
$argvsourcestr = "";
};
};
//die(var_dump('die(var_dump(...)) in '.__FILE__.':'.__LINE__,
//$firstInterestingLineTokenKey,$lastInterestingLineTokenKey,$interestingTokensArray,$tmpstr
//$argvSourceCode));
if (count($argvSourceCode, COUNT_NORMAL) - 1 != $argc) /*-1 because $argvSourceCode[0] is bullshit*/ {
throw new Exception('failed to read source code of all the arguments! (and idk which ones i missed)! sorry..');
};
//</rebuildInterestingSourceCode>
} catch (Exception $ex) {
$argvSourceCode = array(); //clear it
//TODO: failed to read source code
//die("TODO N STUFF..".__FILE__.__LINE__);
$fancy_sourcecode_analyze = false; //ERROR..
if ($debug_hhb_var_dump) {
throw $ex;
} else {/*exception ignored, continue as normal without $fancy_sourcecode_analyze */};
}
unset($xsource, $xToken, $xTokenArray, $firstInterestingLineTokenKey, $lastInterestingLineTokenKey, $xTokenKey, $tmpi, $tmpkey);
};
//</analyzeSourceCode>
$msg = $hhb_var_dump_prepend;
if ($fancy_sourcecode_analyze != $fancy_sourcecode_analyze_setting) {
$msg.= ' (PS: some error analyzing source code)'.PHP_EOL;
};
$msg.=
'in "'.$bt['file'].
'": on line "'.$bt['line'].
'": '.$argc.
' variable'.($argc === 1 ? '' : 's') //because over-engineering ftw?
.PHP_EOL;
if ($fancy_sourcecode_analyze) {
$msg.= ' hhb_var_dump(';
$msg.= implode(",", array_slice($argvSourceCode, 1));//$argvSourceCode[0] is bullshit.
$msg.= ')'.PHP_EOL;
}
//array_unshift($bt,$msg);
echo $msg;
$i = 0;
foreach($argv as &$val) {
echo 'argv['.++$i.']';
if ($fancy_sourcecode_analyze) {
echo ' >>>'.$argvSourceCode[$i].'<<<';
}
echo ':';
if ($use_xdebug_var_dump) {
xdebug_var_dump($val);
} else {
var_dump($val);
};
}
echo $hhb_var_dump_append;
//call_user_func_array("var_dump",$args);
}
hhb_var_dump(empty($_POST['undefined_index_please_dafgwrfrfegjirejgi']));
Warning: "continue" targeting switch is equivalent to "break". Did you mean to use "continue 2"? in /in/FvgWE on line 74
Warning: "continue" targeting switch is equivalent to "break". Did you mean to use "continue 2"? in /in/FvgWE on line 78
HHB_VAR_DUMP_START
in "/in/FvgWE": on line "251": 1 variable
hhb_var_dump(empty($_POST['undefined_index_please_dafgwrfrfegjirejgi']))
argv[1] >>>empty($_POST['undefined_index_please_dafgwrfrfegjirejgi'])<<<:bool(true)
HHB_VAR_DUMP_END
HHB_VAR_DUMP_START
in "/in/FvgWE": on line "251": 1 variable
hhb_var_dump(empty($_POST['undefined_index_please_dafgwrfrfegjirejgi']))
argv[1] >>>empty($_POST['undefined_index_please_dafgwrfrfegjirejgi'])<<<:bool(true)
HHB_VAR_DUMP_END