PageRenderTime 48ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/noutrace.class.php

https://bitbucket.org/lordgnu/xdebug-trace-gui
PHP | 443 lines | 374 code | 24 blank | 45 comment | 12 complexity | eda9e98de22d03e02eee99e86a71759c MD5 | raw file
  1. <?php
  2. class noutrace
  3. {
  4. public $logDirectory;
  5. public $traceFormat;
  6. public $file;
  7. public $memoryAlarm = 0.3;
  8. public $timeAlarm = 0.03;
  9. public $onlyOneInstruction = '';
  10. public $onlyOneScript = '';
  11. public $customNamespace = 'Corretge\\';
  12. public $filesize;
  13. protected $defFN;
  14. public function __construct()
  15. {
  16. $this->logDirectory = ini_get('xdebug.trace_output_dir');
  17. $this->traceFormat = ini_get('xdebug.trace_format');
  18. ini_set('xdebug.auto_trace', 'Off');
  19. }
  20. public function rtvFiles()
  21. {
  22. $ret = '';
  23. $aFiles = array();
  24. $files = new DirectoryIterator($this->logDirectory);
  25. foreach ($files as $file)
  26. {
  27. if (substr_count($file->getFilename(), '.xt') == 0)
  28. {
  29. continue;
  30. }
  31. $date = explode('.', $file->getFilename());
  32. $date = date('Y-m-d H:i:s', $file->getCTime());
  33. if ($file->getFilename() == $this->file)
  34. {
  35. $jSel = ' selected="selected"';
  36. }
  37. else
  38. {
  39. $jSel = '';
  40. }
  41. $aFiles[$date . uniqid()] = '<option value="' . $file->getFilename() . '" ' . $jSel . '> ' . $date . ' - ' . str_replace('_','-',$file->getFilename()) . '-' . number_format($file->getSize() / 1024,
  42. 0,
  43. ',',
  44. '.') . '-KB</option>';
  45. }
  46. ksort($aFiles);
  47. return implode("\n", $aFiles);
  48. }
  49. public function aryComp($a, $b)
  50. {
  51. if ($a['cnt'] == $b['cnt'])
  52. {
  53. return 0;
  54. }
  55. /**
  56. * fem-ho desc
  57. */
  58. return ($a['cnt'] > $b['cnt']) ? -1 : 1;
  59. }
  60. public function usortByArrayKey(&$array, $key, $asc=SORT_ASC)
  61. {
  62. $sort_flags = array(SORT_ASC, SORT_DESC);
  63. if (!in_array($asc, $sort_flags))
  64. throw new InvalidArgumentException('sort flag only accepts SORT_ASC or SORT_DESC');
  65. $cmp = function(array $a, array $b) use ($key, $asc, $sort_flags)
  66. {
  67. if (!is_array($key))
  68. { //just one key and sort direction
  69. if (!isset($a[$key]) || !isset($b[$key]))
  70. {
  71. throw new Exception('attempting to sort on non-existent keys');
  72. }
  73. if ($a[$key] == $b[$key])
  74. return 0;
  75. return ($asc == SORT_ASC xor $a[$key] < $b[$key]) ? 1 : -1;
  76. } else
  77. { //using multiple keys for sort and sub-sort
  78. foreach ($key as $sub_key => $sub_asc)
  79. {
  80. //array can come as 'sort_key'=>SORT_ASC|SORT_DESC or just 'sort_key', so need to detect which
  81. if (!in_array($sub_asc, $sort_flags))
  82. {
  83. $sub_key = $sub_asc;
  84. $sub_asc = $asc;
  85. }
  86. //just like above, except 'continue' in place of return 0
  87. if (!isset($a[$sub_key]) || !isset($b[$sub_key]))
  88. {
  89. throw new Exception('attempting to sort on non-existent keys');
  90. }
  91. if ($a[$sub_key] == $b[$sub_key])
  92. continue;
  93. return ($sub_asc == SORT_ASC xor $a[$sub_key] < $b[$sub_key]) ? 1 : -1;
  94. }
  95. return 0;
  96. }
  97. };
  98. usort($array, $cmp);
  99. }
  100. /**
  101. * establim els paràmetres que ens arriben del formulari.
  102. */
  103. public function setParams()
  104. {
  105. if (isset($_GET['file']))
  106. {
  107. $this->file = basename($_GET['file']);
  108. /**
  109. * mirem que sigui un arxiu vàlid
  110. */
  111. if (!file_exists($this->logDirectory . '/' . $this->file))
  112. {
  113. throw new Exception("Can't access to file " . $this->logDirectory . '/' . $this->file);
  114. }
  115. $this->filesize = filesize($this->logDirectory . '/' . $this->file);
  116. }
  117. if (isset($_GET['onlyOneInstruction']))
  118. {
  119. $this->onlyOneInstruction = ($_GET['onlyOneInstruction']);
  120. }
  121. if (isset($_GET['onlyOneScript']))
  122. {
  123. $this->onlyOneScript = ($_GET['onlyOneScript']);
  124. }
  125. //$this->memoryAlarm = (float) $_GET['memory'];
  126. //$this->timeAlarm = (float) $_GET['time'];
  127. }
  128. /**
  129. * la mare dels ous, la traça
  130. *
  131. * Sense que serveixi de precedents i per un tema de performance, aquest
  132. * mètode escriurà a stdoutput directament.
  133. */
  134. public function trace()
  135. {
  136. /**
  137. * recuperem la llista de funcions, les pròpies de PHP hi
  138. * seran sota ['internal']
  139. */
  140. //$this->defFN = get_defined_functions();
  141. /**
  142. * counter
  143. */
  144. $jCnt = 0;
  145. /**
  146. * Sumary
  147. */
  148. $aSumary = array();
  149. $aSumaryS = array();
  150. /**
  151. * inicialitzem alguns camps
  152. */
  153. $prevLvl = 0;
  154. $prevTim = 0;
  155. $prevMem = 0;
  156. $class = 'odd';
  157. /**
  158. * mirem si ens demanen iniLin
  159. */
  160. if (!isset($_GET['iniLin']))
  161. {
  162. $_GET['iniLin'] = 0;
  163. $ctrlPrimeraLin = false;
  164. }
  165. else
  166. {
  167. $ctrlPrimeraLin = true;
  168. }
  169. $iniLin = (double) $_GET['iniLin'];
  170. $maxLin = $iniLin + 1024;
  171. /**
  172. * mirem si ens demanen una instrucció concreta, llavors no hi ha limit
  173. */
  174. $controlDeLinies = (!empty($this->onlyOneInstruction) or !empty($this->onlyOneScript));
  175. $controlInstruction = !empty($this->onlyOneInstruction);
  176. $controlScript = !empty($this->onlyOneScript);
  177. /**
  178. * només acceptarem tipus de traça 1
  179. */
  180. if ($this->traceFormat != 1)
  181. {
  182. throw new Exception("xdebug.trace_format in /etc/php5/conf.d/xdebug.ini must be 1");
  183. }
  184. $aSteps = array();
  185. /**
  186. * Process all lines
  187. */
  188. $fh = fopen($this->logDirectory . '/' . $this->file, 'r');
  189. $nRow = 0;
  190. $eof = true;
  191. while ($jReadedLine = fgets($fh))
  192. {
  193. $nRow++;
  194. if (!$controlDeLinies and $nRow < $iniLin)
  195. {
  196. continue;
  197. }
  198. $jData = explode("\t", $jReadedLine);
  199. $jDataCnt = count($jData);
  200. /**
  201. * si es tracta de la capçalera de l'arxiu, la mostrem com a info
  202. */
  203. if ($jDataCnt == 1)
  204. {
  205. echo "<pre>$jReadedLine</pre>";
  206. continue;
  207. }
  208. /**
  209. * si és el registre de finalització d'una instrucció, la processem
  210. */
  211. elseif ($jDataCnt == 5)
  212. {
  213. // list($jFLevel, $jFId, $jFPoint, $jFTime, $jFMemory) = $jData;
  214. /**
  215. * Si és el final de tot, no el comptarem, doncs no tenim cap id d'incic
  216. * el mostrarem directament
  217. */
  218. if ($jData[0] == '')
  219. {
  220. echo "<h3>TOTAL " . number_format(count($aSteps), 0) .
  221. " function/method calls in " . number_format($jData[3], 6) . " ms with " .
  222. number_format(((int) $jData[4]) / 1024, 3) . " KB's </h3>";
  223. }
  224. else
  225. {
  226. continue;
  227. /**
  228. * li restem el temps i la memòria
  229. */
  230. $aSteps[$jData[1]][3] = number_format((float) $jData[3] - (float) $aSteps[$jData[1]][3],
  231. 6);
  232. $aSteps[$jData[1]][4] = number_format((float) $jData[4] - (float) $aSteps[$jData[1]][4],
  233. 0);
  234. }
  235. }
  236. /**
  237. * En qualsevol altre cas, és un registre d'inici d'instrucció
  238. */
  239. else
  240. {
  241. // list($jILevel, $jIId, $jIPoint, $jITime, $jIMemory, $jIFunction,
  242. // $jIType, $jIFile, $jIFilename, $jILine, $jINumParms) = $jData;
  243. If ($prevTim == 0)
  244. {
  245. $prevTim = (float) $jData[3];
  246. $prevMem = (float) $jData[4];
  247. if ($iniLin == 0)
  248. {
  249. continue;
  250. }
  251. }
  252. /**
  253. * procedim a fer la sortida
  254. */
  255. /**
  256. * si hi ha un canvi de nivell, en funció de si és
  257. * més petit o més gran,
  258. */
  259. if ($prevLvl < $jData[0])
  260. {
  261. if ($ctrlPrimeraLin)
  262. {
  263. echo str_repeat("<ul>", $jData[0]);
  264. $ctrlPrimeraLin = false;
  265. }
  266. else
  267. {
  268. echo "<ul>";
  269. }
  270. }
  271. elseif ($prevLvl > $jData[0])
  272. {
  273. echo str_repeat("</ul>", $prevLvl - $jData[0]);
  274. }
  275. $prevLvl = $jData[0];
  276. /**
  277. * imprimim, només si es correspon a la instrucció que han demanat.
  278. */
  279. if (!$controlDeLinies or
  280. ($controlInstruction and strpos($this->onlyOneInstruction, $jData[5]) === 0) or
  281. ($controlScript and strpos($jData[8], $this->onlyOneScript) !== false)
  282. )
  283. {
  284. echo "<li title=\"{$nRow}\" class=\"{$class}\">";
  285. /**
  286. * @todo fer-ho via CSS
  287. */
  288. if ($class == 'odd')
  289. {
  290. $class = 'even';
  291. }
  292. else
  293. {
  294. $class = 'odd';
  295. }
  296. echo '<span class="line">';
  297. echo "<a href='trace-code.php?file={$jData[8]}&line={$jData[9]}' target='trace-code'>$jData[9]</a>";
  298. echo "</span>";
  299. echo '<span class="time">';
  300. // echo "ini" . number_format($prevTim, 6) . "<br />";
  301. // echo "end" . number_format((float) $jData[3], 6) . "<br />";
  302. $jSeconds = (float) $jData[3] - $prevTim;
  303. echo number_format($jSeconds * 1000000, 0) . ' µs';
  304. echo "</span>";
  305. echo '<span class="mem">';
  306. // echo "ini" . number_format($prevMem, 0) . "<br />";
  307. // echo "end" . number_format((float) $jData[4], 0) . "<br />";
  308. echo number_format((float) $jData[4] - $prevMem, 0);
  309. echo "</span>";
  310. // list($jILevel, $jIId, $jIPoint, $jITime, $jIMemory, $jIFunction,
  311. // $jIType, $jIFile, $jIFilename, $jILine, $jINumParms) = $jData;
  312. echo '<span class="func">';
  313. echo "<b>{$jData[5]}</b><br/>";
  314. if ($jData[10] > 0)
  315. {
  316. echo "<ul>";
  317. for ($jI = 11; $jI <= 10 + $jData[10]; $jI++)
  318. {
  319. echo "<li class=\"parm\">{$jData[$jI]}</li>";
  320. }
  321. echo "</ul>";
  322. }
  323. elseif (!empty($jData[7]))
  324. {
  325. echo "<ul><li class=\"parm\">{$jData[7]}</li></ul>";
  326. }
  327. echo "<br/>";
  328. echo "<i class=\"pgm\">{$jData[8]}</i>";
  329. echo '</span>';
  330. echo "</li>";
  331. ob_flush();
  332. }
  333. /**
  334. * Si superem el màxim de línies, sortim
  335. */
  336. if (!$controlDeLinies and $nRow > $maxLin)
  337. {
  338. $eof = false;
  339. break;
  340. }
  341. $prevTim = (float) $jData[3];
  342. $prevMem = (float) $jData[4];
  343. $lastLine = $nRow;
  344. }
  345. }
  346. if (!$eof)
  347. {
  348. $_GET['iniLin'] = $lastLine + 1;
  349. echo "<br /><br><a href=\"{$_SERVER['SCRIPT_NAME']}?";
  350. foreach ($_GET as $parm => $val)
  351. {
  352. echo "{$parm}={$val}&";
  353. }
  354. echo "\">next 1024 lines</a>";
  355. }
  356. }
  357. public function debugMem($line, $method = null)
  358. {
  359. echo "<!-- line {$line} memory " . number_format(memory_get_usage(true), 0);
  360. if (isset($method))
  361. {
  362. echo ' method ' . $method;
  363. }
  364. echo " -->";
  365. }
  366. }