getTrace(); $sql = null; foreach ($backtrace as $trace) { switch ($trace['function']) { // Find MySQLi query if there was one! case 'query': case 'real_query': if ( ! isset($trace['class']) || $trace['class'] !== 'mysqli') break; $sql = $trace['args'][0]; // 1st arg in object style (mysqli::query()) break; case 'mysqli_query': case 'mysqli_real_query': $sql = $trace['args'][1]; // 2nd arg in procedural style (mysqli_query()) } } if (isset($sql)) { $backtrace = array_reverse($backtrace); // reverse the array, it feels a bit more natural to see the stack trace in call order! $dump .= '
' . PHP_EOL . 'SQL Query Dump:
' . PHP_EOL . '' . htmlentities($sql) . '
' . PHP_EOL; } break; } $backtrace = $e->getTrace(); $max_file_length = 0; $max_line_length = 0; $internal_function = '[internal function]'; foreach($backtrace as $trace) { if (isset($trace['file'])) { $max_file_length = max($max_file_length, strlen($trace['file'])); $max_line_length = max($max_line_length, strlen($trace['line'])); } else $max_file_length = strlen($internal_function); } $backtrace = array_reverse($backtrace); // reverse the array, it feels a bit more natural to see the stack trace in call order! $dump .= PHP_EOL . PHP_EOL . 'Stack trace:
' . PHP_EOL;
			foreach ($backtrace as $index => $trace)
			{
				$args	= null;
				$comma	= null;
				foreach ($trace['args'] as $arg)
				{
					if (is_string($arg))		$args .= $comma . (strpos($arg,'\'')===false?'\'':'"') . (strlen($arg) > 40 ? substr($arg, 0, 40) . ' ...' : $arg) . (strpos($arg,'\'')===false?'\'':'"');
					else if (is_numeric($arg))	$args .= $comma . $arg;
					else if (is_bool($arg))		$args .= $comma . $arg; // ($arg ? 'true' : 'false')
					else if (is_null($arg))		$args .= $comma . 'null';
					else if (is_array($arg))	$args .= $comma . 'array';
					else if (is_object($arg))	$args .= $comma . '(object) ' . get_class($arg);
					else if (is_callable($arg))	$args .= $comma . 'callable';
					else if (is_resource($arg))	$args .= $comma . 'resource';
					$comma = ', ';
				}
				$dump	.=	str_pad('#' . ($index + 1), 4) .
									(isset($trace['file']) ? (str_pad($trace['file'], $max_file_length) . ' (line: ' . $trace['line'] . ')' . str_repeat(' ', $max_line_length - strlen($trace['line']))) : str_pad($internal_function, $max_file_length + $max_line_length + 9)) . ' ' .
									(isset($trace['class']) ? $trace['class'] . $trace['type'] : null) .
									$trace['function'] . '(' . $args . ')' . PHP_EOL;
			}
			$dump		.=	'
'; // Detect Content-Type $headers = headers_list(); $html = true; $found_content_type = false; foreach ($headers as $header) { if (strpos($header, 'Content-Type:') !== false || strpos($header, 'Content-type:') !== false) { $found_content_type = true; $html = strpos($header, 'text/html') !== false; } } if ( ! $found_content_type && headers_sent() === false) header('Content-Type: text/html; charset=utf-8'); $dump = '
' . PHP_EOL . 'Fatal error: Uncaught ' . get_class($e) . ': ' . htmlentities($e->getMessage()) . ' thrown in ' . $e->getFile() . ' on line ' . $e->getLine() . '

' . PHP_EOL . $dump . PHP_EOL; echo $html ? $dump : html_entity_decode(strip_tags($dump)); exit; }); } }