PHP 7 replacement for xdebug tracing

I started working with PHP 7.0.0-dev and, at least at the time I wrote this, xdebug and Zend debugger are not currently compatible with it, because of the extension API changes.  If you need something better than a simple NOTICE or ERROR, then this will probably work for you.

The code is fairly clean, but could use some improvements, and if you have any suggestions or insights, please comment.

Some Notes

  • Some really nice debugging classes and so forth exist (like kint), but they're huge and do way more than I need them to, and also most won't easily mimic xdebug, if at all.
  • It does not work as well or provide as much detail as xdebug's stack tracing, but it's pretty close and may work for most people.
  • It doesn't provide remote debugging or anything like that, obviously
  • The code, ironically, does not take advantage of any improves made within PHP 7, so it can be used with older versions, but I've only tested it with 5.5 and 5.6

Instructions

I put the code at the top of my entry point (index.php for me) before any other code (autoloader, etc). Of course if you don't have an entry point, you can probably put it in some other global file if you want, such as a config file.

I also put it in the condition of "if (PHP_MAJOR_VERSION == 7) {…}", just in case I test my app with other versions as well.

/* @version 1.0.0 - Just in case I update it here.
 * @license MIT/X11
 * @authors @tonyshowoff
 */
function mojoDebugger($level, $error, $file, $line, $context) {
   $levels = [E_ERROR => 'Error',
              E_WARNING => 'Warning',
              E_PARSE => 'Parse Error',
              E_NOTICE => 'Notice',
              E_CORE_ERROR => 'Core Error',
              E_CORE_WARNING => 'Core Warning',
              E_COMPILE_ERROR => 'Compile Error',
              E_COMPILE_WARNING => 'Compile Warning',
              E_USER_ERROR => 'User Error',
              E_USER_WARNING => 'User Warning',
              E_USER_NOTICE => 'User Notice',
              E_STRICT => 'Strict Notice',
              E_RECOVERABLE_ERROR => 'Recoverable Error'];

   $level = (isset($levels[$level]) ? $levels[$level] : 'Unknown Level [number ' . $level . ']');
   $error = (empty($error) ? 'Unknown error' : $error);
   $file = (empty($file) ? '[unknown file]' : $file);
   $line = (empty($line) ? '0 or unknown' : $line);

   echo $level . ': ' . $error . ' in ' . $file . ' on line ' . $line . "\n\n";

   echo "Backtrace:\n";

   $backtrace = debug_backtrace();
   array_shift($backtrace); // No need to report the debugger itself
   $backtrace = array_reverse($backtrace, True);

   foreach($backtrace as $call => $info) {
      echo "\t" . $call . '. ';

      $func = (empty($info['function']) ? '' : $info['function']);

      if (empty($info['args'])) {
         echo $func . '() ';
      } else {
         $info['args'] = print_r($info['args'], 1);
         $info['args'] = str_replace(["\n", "\t"], '', $info['args']);
         $info['args'] = substr($info['args'], 6);
         $info['args'] = substr($info['args'], 0, -1);
         $info['args'] = trim(str_replace('    ', ' ', $info['args']));
         echo $func . '(' . (strlen($info['args']) > 128 ? substr($info['args'], 0, 128) . '...' : $info['args']) . ') ';
      }

      echo (empty($info['file']) ? '[unknown file]' : $info['file']);
      echo (empty($info['line']) ? ':0 or unknown' : ':' . $info['line']);
      echo "\n";
   }
}

set_error_handler('mojoDebugger', E_ALL | E_WARNING | E_NOTICE | E_STRICT | E_PARSE);