Passed
Push — main ( d7efbc...05d87f )
by Sammy
03:11 queued 01:29
created

Debugger.class.php (1 issue)

Labels
Severity
1
<?php
2
3
namespace HexMakina\Debugger
4
{
5
  trait Debugger
6
  {
7
    public function __debugInfo()
8
    {
9
      return [json_encode(get_object_vars($this))];
10
    }
11
12
    public static function init()
13
    {
14
      // just to load the class, required to get the shortcuts defined in namespace \
15
    }
16
17
    public static function display_errors($error_message=null)
18
    {
19
      $should_display = ini_get('display_errors') == '1';
20
21
      if($should_display && !empty($error_message))
22
        echo('<pre style="z-index:9999; background-color:#FFF; color:#000; padding:0.5em; font-size:0.7em; margin:0 0 1em 0; font-family:courier;">'.$error_message.'</pre>');
23
    }
24
25
    // ----------------------------------------------------------- visual dump (depends on env)
26
    public static function vd($var, $var_name = null, $full_backtrace = false)
27
    {
28
      self::display_errors(self::dump($var, $var_name, $full_backtrace));
29
    }
30
31
    // ----------------------------------------------------------- visual dump and DIE
32
    public static function dd($var, $var_name = null, $full_backtrace = true)
33
    {
34
      self::vd($var, $var_name, $full_backtrace);
35
      die;
36
    }
37
38
    // ----------------------------------------------------------- dump on variable type (Throwables, array, anything else)
39
    public static function dump($var, $var_name = null, $full_backtrace = true)
40
    {
41
      if(is_object($var) && (is_subclass_of($var, 'Error') || is_subclass_of($var, 'Exception')))
42
      {
43
        $backtrace = $var->getTrace();
44
        $full_backtrace = true;
45
        $var_dump  = self::format_throwable_message(get_class($var), $var->getCode(), $var->getFile(), $var->getLine(), $var->getMessage());
46
      }
47
      else
48
      {
49
        $backtrace = debug_backtrace();
50
51
        ob_start();
52
        var_dump($var);
53
        $var_dump = ob_get_clean();
54
      }
55
56
      return PHP_EOL."*******".(empty($var_name) ? '' : " ($var_name) ")."*******".PHP_EOL.self::format_trace($backtrace, $full_backtrace).PHP_EOL.$var_dump;
57
    }
58
59
    // ----------------------------------------------------------- formatting
60
61
    // ----------------------------------------------------------- formatting : first line of \Throwable-based error
62
    public static function format_throwable_message($class, $code, $file, $line, $message)
63
    {
64
      return sprintf(PHP_EOL.'%s (%d) in file %s:%d'.PHP_EOL.'%s', $class, $code, self::format_file($file), $line, $message);
65
    }
66
67
    // ----------------------------------------------------------- formatting : shorten file path to [self::REDUCE_FILE_PATH_DEPTH_TO] elements
68
    public static function format_file($file,$reduce_file_depth_to = 5)
69
    {
70
      return implode('/', array_slice(explode('/', $file), -$reduce_file_depth_to, $reduce_file_depth_to));
71
    }
72
73
    // ----------------------------------------------------------- formatting : nice backtrace
74
    public static function format_trace($traces, $full_backtrace)
75
    {
76
      $formated_traces = [];
77
78
      foreach($traces as $depth => $trace)
79
      {
80
        $function_name = $trace['function'] ?? '?';
81
        $class_name = $trace['class'] ?? '?';
82
83
        if(self::is_debugger_function($class_name, $function_name))
84
          continue;
85
86
        if(!self::is_debugger_call($function_name) && isset($trace['args']))
87
          $args = self::trace_args_to_string($trace['args'])
88
        else
0 ignored issues
show
A parse error occurred: Syntax error, unexpected T_ELSE on line 88 at column 8
Loading history...
89
          $args = microtime(true);
90
91
        $call_file = isset($trace['file']) ? basename($trace['file']) : '?';
92
        $call_line = $trace['line'] ?? '?';
93
94
        $formated_traces []= sprintf('[%-23.23s %3s] %'.($depth*3).'s%s%s(%s)', $call_file, $call_line,' ', "$class_name::", $function_name, $args);
95
96
        if($full_backtrace === false)
97
          break;
98
      }
99
100
      return implode(PHP_EOL, array_reverse($formated_traces));
101
    }
102
103
    private static function trace_args_to_string($trace_args)
104
    {
105
      $ret = [];
106
      foreach($trace_args as $arg)
107
      {
108
        if(is_null($arg))
109
          $ret[]= 'null';
110
        elseif(is_bool($arg))
111
          $ret[]= $arg === true ? 'bool:true' : 'bool:false';
112
        elseif(is_string($arg) || is_numeric($arg))
113
          $ret[]= $arg;
114
        elseif(is_object($arg))
115
          $ret[]= get_class($arg);
116
        elseif(is_array($arg))
117
          $ret[]= 'Array #'.count($arg);
118
        else
119
        {
120
          var_dump($arg);
121
          $ret[] = '!!OTHER!!';
122
        }
123
      }
124
      $ret = implode(', ', $ret);
125
      return $ret;
126
    }
127
128
    private static function is_debugger_function($class_name, $function_name)
129
    {
130
      return $class_name === __CLASS__ && in_array($function_name, ['dump', 'vd', 'dd']);
131
    }
132
133
    private static function is_debugger_call($function_name)
134
    {
135
      return in_array($function_name, ['vd', 'dd','vdt', 'ddt']);
136
    }
137
  }
138
}
139
140
namespace
141
{
142
  if(!function_exists('vd')) {
143
    function vd($var, $var_name=null){  return \HexMakina\Debugger\Debugger::vd($var, $var_name, false);}
144
  }
145
  if(!function_exists('dd')) {
146
    function dd($var, $var_name=null){  return \HexMakina\Debugger\Debugger::dd($var, $var_name, false);}
147
  }
148
  if(!function_exists('vdt')) {
149
    function vdt($var, $var_name=null){  return \HexMakina\Debugger\Debugger::vd($var, $var_name, true);}
150
  }
151
  if(!function_exists('ddt')) {
152
    function ddt($var, $var_name=null){  return \HexMakina\Debugger\Debugger::dd($var, $var_name, true);}
153
  }
154
}
155