/** * Get a stack trace from either PHP or xdebug if present * @return string */ function error_get_stack_trace() { $t_trace = ''; if (extension_loaded('xdebug')) { #check for xdebug presence $t_stack = xdebug_get_function_stack(); # reverse the array in a separate line of code so the # array_reverse() call doesn't appear in the stack $t_stack = array_reverse($t_stack); array_shift($t_stack); #remove the call to this function from the stack trace foreach ($t_stack as $t_frame) { $t_trace .= (isset($t_frame['file']) ? basename($t_frame['file']) : 'UnknownFile') . ' L' . (isset($t_frame['line']) ? $t_frame['line'] : '?') . ' ' . (isset($t_frame['function']) ? $t_frame['function'] : 'UnknownFunction'); $t_args = array(); if (isset($t_frame['params']) && count($t_frame['params']) > 0) { $t_trace .= ' Params: '; foreach ($t_frame['params'] as $t_value) { $t_args[] = error_build_parameter_string($t_value); } $t_trace .= '(' . implode($t_args, ', ') . ')'; } else { $t_trace .= '()'; } $t_trace .= "\n"; } } else { $t_stack = debug_backtrace(); array_shift($t_stack); #remove the call to this function from the stack trace array_shift($t_stack); #remove the call to the error handler from the stack trace foreach ($t_stack as $t_frame) { $t_trace .= (isset($t_frame['file']) ? basename($t_frame['file']) : 'UnknownFile') . ' L' . (isset($t_frame['line']) ? $t_frame['line'] : '?') . ' ' . (isset($t_frame['function']) ? $t_frame['function'] : 'UnknownFunction'); $t_args = array(); if (isset($t_frame['args'])) { foreach ($t_frame['args'] as $t_value) { $t_args[] = error_build_parameter_string($t_value); } $t_trace .= '(' . implode($t_args, ', ') . ')'; } else { $t_trace .= '()'; } $t_trace .= "\n"; } } return $t_trace; }
function error_build_parameter_string($p_param) { if (is_array($p_param)) { $t_results = array(); foreach ($p_param as $t_key => $t_value) { $t_results[] = '[' . error_build_parameter_string($t_key) . ']' . ' => ' . error_build_parameter_string($t_value); } return '{ ' . implode($t_results, ', ') . ' }'; } else { if (is_bool($p_param)) { if ($p_param) { return 'true'; } else { return 'false'; } } else { if (is_float($p_param) || is_int($p_param)) { return $p_param; } else { if (is_null($p_param)) { return 'null'; } else { if (is_object($p_param)) { $t_results = array(); $t_class_name = get_class($p_param); $t_inst_vars = get_object_vars($p_param); foreach ($t_inst_vars as $t_name => $t_value) { $t_results[] = "[{$t_name}]" . ' => ' . error_build_parameter_string($t_value); } return 'Object <$t_class_name> ( ' . implode($t_results, ', ') . ' )'; } else { if (is_string($p_param)) { return "'{$p_param}'"; } } } } } } }
/** * Build a string describing the parameters to a function * @param string|array|object $p_param Parameter. * @param boolean $p_showtype Default true. * @param integer $p_depth Default 0. * @return string */ function error_build_parameter_string($p_param, $p_showtype = true, $p_depth = 0) { if ($p_depth++ > 10) { return '<strong>***Nesting Level Too Deep***</strong>'; } if (is_array($p_param)) { $t_results = array(); foreach ($p_param as $t_key => $t_value) { $t_results[] = '[' . error_build_parameter_string($t_key, false, $p_depth) . '] => ' . error_build_parameter_string($t_value, false, $p_depth); } return '<array> { ' . implode($t_results, ', ') . ' }'; } else { if (is_object($p_param)) { $t_results = array(); $t_class_name = get_class($p_param); $t_inst_vars = get_object_vars($p_param); foreach ($t_inst_vars as $t_name => $t_value) { $t_results[] = '[' . $t_name . '] => ' . error_build_parameter_string($t_value, false, $p_depth); } return '<Object><' . $t_class_name . '> ( ' . implode($t_results, ', ') . ' )'; } else { if ($p_showtype) { return '<' . gettype($p_param) . '>' . var_export($p_param, true); } else { return var_export($p_param, true); } } } }