PageRenderTime 23ms CodeModel.GetById 12ms app.highlight 7ms RepoModel.GetById 1ms app.codeStats 0ms

/upload/develop/profiler/profiler_dbg.php

http://torrentpier2.googlecode.com/
PHP | 373 lines | 178 code | 33 blank | 162 comment | 7 complexity | 114a681186a54f0527e92069ca76a54f MD5 | raw file
  1<?php
  2
  3/*
  4 Original from http://forum.dklab.ru/php/advises/ProfaylerForScriptsOnPhp.html
  5 completely rewritten by Meithar
  6
  7 Usage of profiler script:
  8  1. Setup 'php_dbg' [http://dd.cron.ru/dbg/] module on your php.ini
  9  2. Run DBG Listener
 10  3. Include this file at the end of you script
 11  4. To enable profiling use you script with parameters: ?DBGSESSID=1@clienthost:7869;p=1
 12     P.S.: see parameters bellow
 13  5. To disable profiling use you script with parameters: ?DBGSESSID=-1
 14
 15  P.S. All DBGSESSID parameters stored in cookie. You must run in once to enable, and
 16       once to disable.
 17
 18
 19 *****************************************************************************
 20 DBGSESSID Usage:
 21 *****************************************************************************
 22
 23 DBGSESSID=nnn[@host][:port][;{flags}]
 24
 25 where
 26
 27 nnn - is session ID (any positive number or zero)
 28  NOTE: negative values prohibit debug session to run and drops cookie
 29
 30 host - is host name or IP address of the host where your run PHPED IDE.
 31  You may set clienthost which is a keyword, in this case debugger looks for
 32  proper client IP address automatically.
 33
 34 flags - set of the following flags delimited with commas:
 35  s=skip - skip number of HTTP requests before actual session should run
 36  d={0|1} - start debug session
 37  p={0|1} - start profiler session
 38
 39 For example:
 40  DBGSESSID=1@clienthost:7869;d=1,p=1
 41  DBGSESSID=1;d=1,p=0
 42  DBGSESSID=1:7869;d=1,p=0,s=5
 43
 44On/Off:
 45	javascript: document.cookie = 'DBGSESSID=' + escape('1;d=1,p=0') + '; path=/'; document.execCommand('refresh');
 46	javascript: document.cookie = 'DBGSESSID=' + escape('1;d=0,p=0') + '; path=/'; document.execCommand('refresh');
 47
 48	javascript:location.href=location.protocol+'//'+location.hostname+location.pathname+'?DBGSESSID=1;d=1,p=0'
 49	javascript:location.href=location.protocol+'//'+location.hostname+location.pathname+'?DBGSESSID=-1
 50
 51 *****************************************************************************
 52 PHP_DBG Module functions
 53 *****************************************************************************
 54
 55
 56 ---------------------------------------------------
 57 get all profiler results
 58 ---------------------------------------------------
 59 int dbg_get_profiler_results(array &$results);
 60
 61 return int: count of $results
 62
 63 $results = array(
 64             'mod_no'    => array(),
 65             'line_no'   => array(),
 66             'hit_count' => array(),
 67             'tm_max'    => array(),
 68             'tm_min'    => array(),
 69             'tm_sum'    => array(),
 70            );
 71
 72
 73 ---------------------------------------------------
 74 get all modules name
 75 ---------------------------------------------------
 76 int dbg_get_all_module_names(array &$results);
 77
 78 return int: count of $results
 79
 80 $results = array(
 81             'mod_no'   => array(),
 82             'mod_name' => array(),
 83            );
 84
 85
 86 ---------------------------------------------------
 87 get module name
 88 ---------------------------------------------------
 89 int dbg_get_module_name(int $mod_no, string &$results);
 90
 91 return int: 0 - error
 92             1 - success
 93
 94 $results = module name
 95
 96
 97 ---------------------------------------------------
 98 get all context (function name) for given module
 99 ---------------------------------------------------
100 int dbg_get_all_contexts(int $mod_no, array &$results);
101
102 if $mod_no = 0 it returns all contexts
103
104 return int: count of $results
105
106 $results = array(
107             'ctx_no'   => array(),
108             'mod_no'   => array(),
109             'ctx_name' => array(),
110            );
111
112
113 ---------------------------------------------------
114 get context name
115 ---------------------------------------------------
116 int dbg_get_context_name(int $ctx_no, string &$function_name);
117
118 return int: 0 - error
119             1 - success
120
121 $function_name = function name
122
123
124 ---------------------------------------------------
125 get all source lines for given module
126 ---------------------------------------------------
127 int dbg_get_all_source_lines(int $mod_no, array &$results);
128
129 if $mod_no = 0 it returns all source lines for all contexts
130
131 return int: count of $results
132
133 $results = array(
134             'ctx_no'  => array(),
135             'mod_no'  => array(),
136             'line_no' => array(),
137            );
138
139
140 ---------------------------------------------------
141 get context id for given module and line
142 ---------------------------------------------------
143 int dbg_get_source_context(int $mod_no, int $line_no, int &$ctx_no);
144
145 return int: 0 - error
146             1 - success
147
148 $ctx_no = function name
149
150*/
151
152##############################################################################
153
154class profiler_dbg extends profiler
155{
156	var $min_time   = 0;
157	var $total_time = 0;
158
159	//  $min_time - ??????????? ????? ?????????? ??? ?????? ? ????????? ??????????? ?????????? (? ???????? ??? %)
160	//
161	function print_profile_data ($min_time = 0)
162	{
163		// Get all profiling data
164		dbg_get_profiler_results (&$results); # prn($results);
165		dbg_get_all_module_names (&$modules);
166		dbg_get_all_contexts     (0, &$context);
167		dbg_get_all_source_lines (0, &$lines);
168
169		$this->total_time = array_sum($results['tm_sum']);
170		$this->min_time = strpos($min_time, '%') ? $this->total_time * floatval($min_time)/100 : floatval($min_time);
171		$percent = ($this->total_time) ? 100/$this->total_time : 0;
172
173		$module_names = $context_names = $context_lines = $profile = array();
174
175		// Module names
176		foreach ($modules['mod_no'] as $id => $module_no)
177		{
178			$module_names[$module_no] = $modules['mod_name'][$id];
179
180			$profile[$module_no]['time'] = 0;
181			$profile[$module_no]['.'] = array();
182		}
183
184		// Context names
185		foreach ($context['mod_no'] as $id => $context_no)
186		{
187			$module_no = $context['ctx_no'][$id];
188			$ctx_name  = $context['ctx_name'][$id];
189
190			$context_names[$context_no] = ($ctx_name) ? "$ctx_name()" : 'GLOBAL';
191
192			$profile[$module_no]['.'][$context_no]['time'] = 0;
193			$profile[$module_no]['.'][$context_no]['.'] = array();
194		}
195
196		// Context lines
197		foreach ($lines['line_no'] as $id => $line_no)
198		{
199			$module_no = $lines['mod_no'][$id];
200
201			$context_lines[$module_no][$line_no] = $lines['ctx_no'][$id];
202		}
203
204		// Build profiling data
205		foreach ($results['line_no'] as $id => $line_no)
206		{
207			$module_no  = $results['mod_no'][$id];
208			$context_no = $context_lines[$module_no][$line_no];
209
210			$profile[$module_no]['time'] += $results['tm_sum'][$id];
211			$profile[$module_no]['.'][$context_no]['time'] += $results['tm_sum'][$id];
212
213			if ($results['tm_sum'][$id] < $this->min_time)
214			{
215				continue;
216			}
217
218			$profile[$module_no]['.'][$context_no]['.'][$line_no] = array(
219				'time' => $results['tm_sum'][$id],
220				'hits' => $results['hit_count'][$id],
221			);
222		}
223
224		// Sort profiling data: modules, contexts and lines
225		uasort($profile, array(__CLASS__, 'sort_by_time_desc'));
226
227		foreach ($profile as $module_no => $context)
228		{
229			uasort($profile[$module_no]['.'], array(__CLASS__, 'sort_by_time_desc'));
230
231			foreach ($context['.'] as $context_no => $lines)
232			{
233				uasort($profile[$module_no]['.'][$context_no]['.'], array(__CLASS__, 'sort_by_time_desc'));
234			}
235		}
236
237		// Display profiling data
238		$colspan   = 6;
239		$row_class = 'profRow1';
240
241		// Replacements for cleaning highlighted code
242		$highlight_replacements = array(
243			'<code>'     => '',
244			'</code>'    => '',
245			'&nbsp;'     => ' ',
246			'>&lt;?php'  => '>',
247			'?&gt;<'     => '<',
248			'>&lt;?<'    => '><',
249			'>php '      => '>',
250		);
251
252		echo '
253			<div id="profContainer">
254			<table>
255			<tbody>
256		';
257		// Modules
258		foreach ($profile as $module_no => $context)
259		{
260			$module_path = $module_names[$module_no];
261			$module_name = basename($module_path);
262			$module_src  = is_file($module_path) ? file($module_path) : array();
263			$module_time = sprintf('%.4f', $context['time']);
264			$module_perc = sprintf('%.1f', $context['time']*$percent);
265
266			if ($module_time < $this->min_time)
267			{
268				continue;
269			}
270
271			echo '
272				</tbody>
273				</table>
274				<table cellspacing="1" cellpadding="2" border="0" class="profTable">
275				<thead>
276					<tr>
277						<td colspan="'. $colspan .'" class="profFile">' . "[ <b>$module_perc%</b>, $module_time sec. ] :: <b>$module_name</b> " . '</td>
278					</tr>
279					<tr>
280						<td class="profHead">&nbsp;&nbsp;%&nbsp;&nbsp;</td>
281						<td class="profHead">&nbsp;time&nbsp;</td>
282						<td class="profHead">&nbsp;&nbsp;avg&nbsp;&nbsp;</td>
283						<td class="profHead">&nbsp;hits&nbsp;</td>
284						<td class="profHead">&nbsp;line&nbsp;</td>
285						<td class="profHead" width="100%" style="text-align: left;"> source </td>
286					</tr>
287				</thead>
288				<tbody>
289			'."\n";
290
291			// Context
292			foreach ($context['.'] as $context_no => $lines)
293			{
294				$context_name = $context_names[$context_no];
295				$context_time = $this->get_ms($lines['time']);
296				$context_perc = sprintf('%.2f', $lines['time']*$percent);
297				$row_class    = ($row_class == 'profRow1') ? 'profRow2' : 'profRow1';
298
299				if ($lines['time'] < $this->min_time)
300				{
301					continue;
302				}
303
304				echo '
305					<tr>
306						<td colspan="2" class="profFunc funcTime">'. "<b>$context_perc%</b>" .'</td>
307						<td colspan="2" class="profFunc funcTime">'. "<b>$context_time</b> ms" .'</td>
308						<td colspan="'. ($colspan-4) .'" class="profFunc funcName">'. $context_name .'</td>
309					</tr>
310				';
311
312				// Lines
313				foreach ($lines['.'] as $line_no => $data)
314				{
315					$line_perc = $data['time']*$percent;
316					$line_perc = ($line_perc > 0.05) ? sprintf('%.1f', $line_perc) : '';
317					$line_hits = ($data['hits'] != 1) ? $data['hits'] : '';
318					$line_link = '<a class="srcOpen" href="#" onClick="OpenInEditor(\''. addslashes($module_path) ."', $line_no); return false;\">". $line_no .'</a>';
319					$line_time_sum = $this->get_ms($data['time']);
320					$line_time_avg = ($line_hits) ? $this->get_ms($data['time']/$line_hits, 3) : '';
321
322					$perc_class = 'perc';
323					if      ($line_perc > 5) $perc_class .= ' high5';
324					elseif ($line_perc > 3) $perc_class .= ' high3';
325					elseif ($line_perc > 1) $perc_class .= ' high1';
326
327					if ($line_src =& $module_src[$line_no-1])
328					{
329						$line_src = preg_replace('#\s+#', ' ', trim($line_src));
330						$line_src = highlight_string("<?php $line_src", true);
331						$line_src = strtr($line_src, $highlight_replacements);
332					}
333
334					echo '
335						<tr class="'. $row_class .'">
336							<td class="profTD '. $perc_class .'">'. $line_perc .'</td>
337							<td class="profTD time">'. $line_time_sum .'</td>
338							<td class="profTD avg">'.  $line_time_avg  .'</td>
339							<td class="profTD hits">'. $line_hits .'</td>
340							<td class="profTD line">'. $line_link .'</td>
341							<td class="profTD scr" nowrap="nowrap">'. $line_src .'</td>
342						</tr>
343					'."\n";
344				} // Lines
345			} // Context
346		} // Modules
347
348		echo '
349			</tbody></table>
350			<table cellspacing="1" cellpadding="2" border="0" class="profTable">
351				<tr>
352					<td class="files">
353						<div><b>[ '. count($modules['mod_name']) .' files, '. sprintf('%.3f', $this->total_time) .' sec. ]</b></div>
354						<div>'. join('<br />', $modules['mod_name']) .'</div>
355					</td>
356				</tr>
357			</table>
358			</div>
359			<br clear="all" />
360		';
361	}
362
363	function get_ms ($time, $precision = 2)
364	{
365		return ($time < 0.001) ? round($time*1000, $precision) : round($time*1000, 0);
366	}
367
368	static function sort_by_time_desc ($a, $b)
369	{
370		if ($a['time'] == $b['time']) return 0;
371		return ($a['time'] > $b['time']) ? -1 : 1;
372	}
373}