1: <?php namespace Laravel\Profiling;
2:
3: use Laravel\View;
4: use Laravel\File;
5: use Laravel\Event;
6: use Laravel\Config;
7: use Laravel\Request;
8: use Laravel\Database;
9:
10: class Profiler {
11:
12: 13: 14: 15: 16:
17: protected static $data = array('queries' => array(), 'logs' => array(), 'timers' => array());
18:
19: 20: 21: 22: 23: 24:
25: public static function render($response)
26: {
27:
28:
29:
30: if ( ! Request::ajax() and Config::get('application.profiler') )
31: {
32: static::$data['memory'] = get_file_size(memory_get_usage(true));
33: static::$data['memory_peak'] = get_file_size(memory_get_peak_usage(true));
34: static::$data['time'] = number_format((microtime(true) - LARAVEL_START) * 1000, 2);
35: foreach ( static::$data['timers'] as &$timer)
36: {
37: $timer['running_time'] = number_format((microtime(true) - $timer['start'] ) * 1000, 2);
38: }
39:
40: return render('path: '.__DIR__.'/template'.BLADE_EXT, static::$data);
41: }
42: }
43:
44: 45: 46: 47: 48: 49: 50:
51: public static function time( $func, $name = 'default_func_timer' )
52: {
53:
54: $start = microtime(true);
55: $func();
56: $end = microtime(true);
57:
58:
59: if (isset(static::$data['timers'][$name]))
60: {
61: $name = $name.uniqid();
62: }
63:
64:
65: static::$data['timers'][$name]['start'] = $start;
66: static::$data['timers'][$name]['end'] = $end;
67: static::$data['timers'][$name]['time'] = number_format(($end - $start) * 1000, 2);
68: }
69:
70: 71: 72: 73: 74: 75:
76: public static function tick($name = 'default_timer', $callback = null)
77: {
78: $name = trim($name);
79: if (empty($name)) $name = 'default_timer';
80:
81:
82: if (isset(static::$data['timers'][$name]))
83: {
84: $current_timer = static::$data['timers'][$name];
85: $ticks = count($current_timer['ticks']);
86:
87:
88: $new_tick = array();
89: $mt = microtime(true);
90: $new_tick['raw_time'] = $mt - $current_timer['start'];
91: $new_tick['time'] = number_format(($mt - $current_timer['start']) * 1000, 2);
92:
93:
94: if ($ticks > 0)
95: {
96: $last_tick = $current_timer['ticks'][$ticks- 1]['raw_time'];
97: $new_tick['diff'] = number_format(($new_tick['raw_time'] - $last_tick) * 1000, 2);
98: }
99: else
100: {
101: $new_tick['diff'] = $new_tick['time'];
102: }
103:
104:
105: static::$data['timers'][$name]['ticks'][] = $new_tick;
106: }
107: else
108: {
109:
110: static::$data['timers'][$name]['start'] = microtime(true);
111: static::$data['timers'][$name]['ticks'] = array();
112: }
113:
114:
115: if ( ! is_null($callback) and is_callable($callback))
116: {
117:
118: call_user_func_array($callback, array(
119: static::$data['timers'][$name]
120: ));
121: }
122: }
123:
124: 125: 126: 127: 128: 129: 130:
131: public static function log($type, $message)
132: {
133: static::$data['logs'][] = array($type, $message);
134: }
135:
136: 137: 138: 139: 140: 141: 142: 143:
144: public static function query($sql, $bindings, $time)
145: {
146: foreach ($bindings as $binding)
147: {
148: $binding = Database::escape($binding);
149:
150: $sql = preg_replace('/\?/', $binding, $sql, 1);
151: $sql = htmlspecialchars($sql, ENT_QUOTES, 'UTF-8', false);
152: }
153:
154: static::$data['queries'][] = array($sql, $time);
155: }
156:
157: 158: 159: 160: 161:
162: public static function attach()
163: {
164:
165:
166:
167: Event::listen('laravel.log', function($type, $message)
168: {
169: Profiler::log($type, $message);
170: });
171:
172: Event::listen('laravel.query', function($sql, $bindings, $time)
173: {
174: Profiler::query($sql, $bindings, $time);
175: });
176:
177:
178:
179:
180: Event::listen('laravel.done', function($response)
181: {
182: echo Profiler::render($response);
183: });
184: }
185:
186: }
187: