PageRenderTime 61ms CodeModel.GetById 31ms RepoModel.GetById 0ms app.codeStats 1ms

/client/system/libraries/Profiler.php

https://bitbucket.org/jerwinse/iagh-cms
PHP | 558 lines | 333 code | 97 blank | 128 comment | 33 complexity | cad7e9a9a1f43b1a52dcf2e24663188a MD5 | raw file
  1. <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
  2. /**
  3. * CodeIgniter
  4. *
  5. * An open source application development framework for PHP 5.1.6 or newer
  6. *
  7. * @package CodeIgniter
  8. * @author ExpressionEngine Dev Team
  9. * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc.
  10. * @license http://codeigniter.com/user_guide/license.html
  11. * @link http://codeigniter.com
  12. * @since Version 1.0
  13. * @filesource
  14. */
  15. // ------------------------------------------------------------------------
  16. /**
  17. * CodeIgniter Profiler Class
  18. *
  19. * This class enables you to display benchmark, query, and other data
  20. * in order to help with debugging and optimization.
  21. *
  22. * Note: At some point it would be good to move all the HTML in this class
  23. * into a set of template files in order to allow customization.
  24. *
  25. * @package CodeIgniter
  26. * @subpackage Libraries
  27. * @category Libraries
  28. * @author ExpressionEngine Dev Team
  29. * @link http://codeigniter.com/user_guide/general/profiling.html
  30. */
  31. class CI_Profiler {
  32. protected $_available_sections = array(
  33. 'benchmarks',
  34. 'get',
  35. 'memory_usage',
  36. 'post',
  37. 'uri_string',
  38. 'controller_info',
  39. 'queries',
  40. 'http_headers',
  41. 'session_data',
  42. 'config'
  43. );
  44. protected $_query_toggle_count = 25;
  45. protected $CI;
  46. // --------------------------------------------------------------------
  47. public function __construct($config = array())
  48. {
  49. $this->CI =& get_instance();
  50. $this->CI->load->language('profiler');
  51. if (isset($config['query_toggle_count']))
  52. {
  53. $this->_query_toggle_count = (int) $config['query_toggle_count'];
  54. unset($config['query_toggle_count']);
  55. }
  56. // default all sections to display
  57. foreach ($this->_available_sections as $section)
  58. {
  59. if ( ! isset($config[$section]))
  60. {
  61. $this->_compile_{$section} = TRUE;
  62. }
  63. }
  64. $this->set_sections($config);
  65. }
  66. // --------------------------------------------------------------------
  67. /**
  68. * Set Sections
  69. *
  70. * Sets the private _compile_* properties to enable/disable Profiler sections
  71. *
  72. * @param mixed
  73. * @return void
  74. */
  75. public function set_sections($config)
  76. {
  77. foreach ($config as $method => $enable)
  78. {
  79. if (in_array($method, $this->_available_sections))
  80. {
  81. $this->_compile_{$method} = ($enable !== FALSE) ? TRUE : FALSE;
  82. }
  83. }
  84. }
  85. // --------------------------------------------------------------------
  86. /**
  87. * Auto Profiler
  88. *
  89. * This function cycles through the entire array of mark points and
  90. * matches any two points that are named identically (ending in "_start"
  91. * and "_end" respectively). It then compiles the execution times for
  92. * all points and returns it as an array
  93. *
  94. * @return array
  95. */
  96. protected function _compile_benchmarks()
  97. {
  98. $profile = array();
  99. foreach ($this->CI->benchmark->marker as $key => $val)
  100. {
  101. // We match the "end" marker so that the list ends
  102. // up in the order that it was defined
  103. if (preg_match("/(.+?)_end/i", $key, $match))
  104. {
  105. if (isset($this->CI->benchmark->marker[$match[1].'_end']) AND isset($this->CI->benchmark->marker[$match[1].'_start']))
  106. {
  107. $profile[$match[1]] = $this->CI->benchmark->elapsed_time($match[1].'_start', $key);
  108. }
  109. }
  110. }
  111. // Build a table containing the profile data.
  112. // Note: At some point we should turn this into a template that can
  113. // be modified. We also might want to make this data available to be logged
  114. $output = "\n\n";
  115. $output .= '<fieldset id="ci_profiler_benchmarks" style="border:1px solid #900;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';
  116. $output .= "\n";
  117. $output .= '<legend style="color:#900;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_benchmarks').'&nbsp;&nbsp;</legend>';
  118. $output .= "\n";
  119. $output .= "\n\n<table style='width:100%'>\n";
  120. foreach ($profile as $key => $val)
  121. {
  122. $key = ucwords(str_replace(array('_', '-'), ' ', $key));
  123. $output .= "<tr><td style='padding:5px;width:50%;color:#000;font-weight:bold;background-color:#ddd;'>".$key."&nbsp;&nbsp;</td><td style='padding:5px;width:50%;color:#900;font-weight:normal;background-color:#ddd;'>".$val."</td></tr>\n";
  124. }
  125. $output .= "</table>\n";
  126. $output .= "</fieldset>";
  127. return $output;
  128. }
  129. // --------------------------------------------------------------------
  130. /**
  131. * Compile Queries
  132. *
  133. * @return string
  134. */
  135. protected function _compile_queries()
  136. {
  137. $dbs = array();
  138. // Let's determine which databases are currently connected to
  139. foreach (get_object_vars($this->CI) as $CI_object)
  140. {
  141. if (is_object($CI_object) && is_subclass_of(get_class($CI_object), 'CI_DB') )
  142. {
  143. $dbs[] = $CI_object;
  144. }
  145. }
  146. if (count($dbs) == 0)
  147. {
  148. $output = "\n\n";
  149. $output .= '<fieldset id="ci_profiler_queries" style="border:1px solid #0000FF;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';
  150. $output .= "\n";
  151. $output .= '<legend style="color:#0000FF;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_queries').'&nbsp;&nbsp;</legend>';
  152. $output .= "\n";
  153. $output .= "\n\n<table style='border:none; width:100%;'>\n";
  154. $output .="<tr><td style='width:100%;color:#0000FF;font-weight:normal;background-color:#eee;padding:5px'>".$this->CI->lang->line('profiler_no_db')."</td></tr>\n";
  155. $output .= "</table>\n";
  156. $output .= "</fieldset>";
  157. return $output;
  158. }
  159. // Load the text helper so we can highlight the SQL
  160. $this->CI->load->helper('text');
  161. // Key words we want bolded
  162. $highlight = array('SELECT', 'DISTINCT', 'FROM', 'WHERE', 'AND', 'LEFT&nbsp;JOIN', 'ORDER&nbsp;BY', 'GROUP&nbsp;BY', 'LIMIT', 'INSERT', 'INTO', 'VALUES', 'UPDATE', 'OR&nbsp;', 'HAVING', 'OFFSET', 'NOT&nbsp;IN', 'IN', 'LIKE', 'NOT&nbsp;LIKE', 'COUNT', 'MAX', 'MIN', 'ON', 'AS', 'AVG', 'SUM', '(', ')');
  163. $output = "\n\n";
  164. $count = 0;
  165. foreach ($dbs as $db)
  166. {
  167. $count++;
  168. $hide_queries = (count($db->queries) > $this->_query_toggle_count) ? ' display:none' : '';
  169. $show_hide_js = '(<span style="cursor: pointer;" onclick="var s=document.getElementById(\'ci_profiler_queries_db_'.$count.'\').style;s.display=s.display==\'none\'?\'\':\'none\';this.innerHTML=this.innerHTML==\''.$this->CI->lang->line('profiler_section_hide').'\'?\''.$this->CI->lang->line('profiler_section_show').'\':\''.$this->CI->lang->line('profiler_section_hide').'\';">'.$this->CI->lang->line('profiler_section_hide').'</span>)';
  170. if ($hide_queries != '')
  171. {
  172. $show_hide_js = '(<span style="cursor: pointer;" onclick="var s=document.getElementById(\'ci_profiler_queries_db_'.$count.'\').style;s.display=s.display==\'none\'?\'\':\'none\';this.innerHTML=this.innerHTML==\''.$this->CI->lang->line('profiler_section_show').'\'?\''.$this->CI->lang->line('profiler_section_hide').'\':\''.$this->CI->lang->line('profiler_section_show').'\';">'.$this->CI->lang->line('profiler_section_show').'</span>)';
  173. }
  174. $output .= '<fieldset style="border:1px solid #0000FF;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';
  175. $output .= "\n";
  176. $output .= '<legend style="color:#0000FF;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_database').':&nbsp; '.$db->database.'&nbsp;&nbsp;&nbsp;'.$this->CI->lang->line('profiler_queries').': '.count($db->queries).'&nbsp;&nbsp;'.$show_hide_js.'</legend>';
  177. $output .= "\n";
  178. $output .= "\n\n<table style='width:100%;{$hide_queries}' id='ci_profiler_queries_db_{$count}'>\n";
  179. if (count($db->queries) == 0)
  180. {
  181. $output .= "<tr><td style='width:100%;color:#0000FF;font-weight:normal;background-color:#eee;padding:5px;'>".$this->CI->lang->line('profiler_no_queries')."</td></tr>\n";
  182. }
  183. else
  184. {
  185. foreach ($db->queries as $key => $val)
  186. {
  187. $time = number_format($db->query_times[$key], 4);
  188. $val = highlight_code($val, ENT_QUOTES);
  189. foreach ($highlight as $bold)
  190. {
  191. $val = str_replace($bold, '<strong>'.$bold.'</strong>', $val);
  192. }
  193. $output .= "<tr><td style='padding:5px; vertical-align: top;width:1%;color:#900;font-weight:normal;background-color:#ddd;'>".$time."&nbsp;&nbsp;</td><td style='padding:5px; color:#000;font-weight:normal;background-color:#ddd;'>".$val."</td></tr>\n";
  194. }
  195. }
  196. $output .= "</table>\n";
  197. $output .= "</fieldset>";
  198. }
  199. return $output;
  200. }
  201. // --------------------------------------------------------------------
  202. /**
  203. * Compile $_GET Data
  204. *
  205. * @return string
  206. */
  207. protected function _compile_get()
  208. {
  209. $output = "\n\n";
  210. $output .= '<fieldset id="ci_profiler_get" style="border:1px solid #cd6e00;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';
  211. $output .= "\n";
  212. $output .= '<legend style="color:#cd6e00;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_get_data').'&nbsp;&nbsp;</legend>';
  213. $output .= "\n";
  214. if (count($_GET) == 0)
  215. {
  216. $output .= "<div style='color:#cd6e00;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->lang->line('profiler_no_get')."</div>";
  217. }
  218. else
  219. {
  220. $output .= "\n\n<table style='width:100%; border:none'>\n";
  221. foreach ($_GET as $key => $val)
  222. {
  223. if ( ! is_numeric($key))
  224. {
  225. $key = "'".$key."'";
  226. }
  227. $output .= "<tr><td style='width:50%;color:#000;background-color:#ddd;padding:5px'>&#36;_GET[".$key."]&nbsp;&nbsp; </td><td style='width:50%;padding:5px;color:#cd6e00;font-weight:normal;background-color:#ddd;'>";
  228. if (is_array($val))
  229. {
  230. $output .= "<pre>" . htmlspecialchars(stripslashes(print_r($val, true))) . "</pre>";
  231. }
  232. else
  233. {
  234. $output .= htmlspecialchars(stripslashes($val));
  235. }
  236. $output .= "</td></tr>\n";
  237. }
  238. $output .= "</table>\n";
  239. }
  240. $output .= "</fieldset>";
  241. return $output;
  242. }
  243. // --------------------------------------------------------------------
  244. /**
  245. * Compile $_POST Data
  246. *
  247. * @return string
  248. */
  249. protected function _compile_post()
  250. {
  251. $output = "\n\n";
  252. $output .= '<fieldset id="ci_profiler_post" style="border:1px solid #009900;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';
  253. $output .= "\n";
  254. $output .= '<legend style="color:#009900;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_post_data').'&nbsp;&nbsp;</legend>';
  255. $output .= "\n";
  256. if (count($_POST) == 0)
  257. {
  258. $output .= "<div style='color:#009900;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->lang->line('profiler_no_post')."</div>";
  259. }
  260. else
  261. {
  262. $output .= "\n\n<table style='width:100%'>\n";
  263. foreach ($_POST as $key => $val)
  264. {
  265. if ( ! is_numeric($key))
  266. {
  267. $key = "'".$key."'";
  268. }
  269. $output .= "<tr><td style='width:50%;padding:5px;color:#000;background-color:#ddd;'>&#36;_POST[".$key."]&nbsp;&nbsp; </td><td style='width:50%;padding:5px;color:#009900;font-weight:normal;background-color:#ddd;'>";
  270. if (is_array($val))
  271. {
  272. $output .= "<pre>" . htmlspecialchars(stripslashes(print_r($val, TRUE))) . "</pre>";
  273. }
  274. else
  275. {
  276. $output .= htmlspecialchars(stripslashes($val));
  277. }
  278. $output .= "</td></tr>\n";
  279. }
  280. $output .= "</table>\n";
  281. }
  282. $output .= "</fieldset>";
  283. return $output;
  284. }
  285. // --------------------------------------------------------------------
  286. /**
  287. * Show query string
  288. *
  289. * @return string
  290. */
  291. protected function _compile_uri_string()
  292. {
  293. $output = "\n\n";
  294. $output .= '<fieldset id="ci_profiler_uri_string" style="border:1px solid #000;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';
  295. $output .= "\n";
  296. $output .= '<legend style="color:#000;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_uri_string').'&nbsp;&nbsp;</legend>';
  297. $output .= "\n";
  298. if ($this->CI->uri->uri_string == '')
  299. {
  300. $output .= "<div style='color:#000;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->lang->line('profiler_no_uri')."</div>";
  301. }
  302. else
  303. {
  304. $output .= "<div style='color:#000;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->uri->uri_string."</div>";
  305. }
  306. $output .= "</fieldset>";
  307. return $output;
  308. }
  309. // --------------------------------------------------------------------
  310. /**
  311. * Show the controller and function that were called
  312. *
  313. * @return string
  314. */
  315. protected function _compile_controller_info()
  316. {
  317. $output = "\n\n";
  318. $output .= '<fieldset id="ci_profiler_controller_info" style="border:1px solid #995300;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';
  319. $output .= "\n";
  320. $output .= '<legend style="color:#995300;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_controller_info').'&nbsp;&nbsp;</legend>';
  321. $output .= "\n";
  322. $output .= "<div style='color:#995300;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->router->fetch_class()."/".$this->CI->router->fetch_method()."</div>";
  323. $output .= "</fieldset>";
  324. return $output;
  325. }
  326. // --------------------------------------------------------------------
  327. /**
  328. * Compile memory usage
  329. *
  330. * Display total used memory
  331. *
  332. * @return string
  333. */
  334. protected function _compile_memory_usage()
  335. {
  336. $output = "\n\n";
  337. $output .= '<fieldset id="ci_profiler_memory_usage" style="border:1px solid #5a0099;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';
  338. $output .= "\n";
  339. $output .= '<legend style="color:#5a0099;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_memory_usage').'&nbsp;&nbsp;</legend>';
  340. $output .= "\n";
  341. if (function_exists('memory_get_usage') && ($usage = memory_get_usage()) != '')
  342. {
  343. $output .= "<div style='color:#5a0099;font-weight:normal;padding:4px 0 4px 0'>".number_format($usage).' bytes</div>';
  344. }
  345. else
  346. {
  347. $output .= "<div style='color:#5a0099;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->lang->line('profiler_no_memory')."</div>";
  348. }
  349. $output .= "</fieldset>";
  350. return $output;
  351. }
  352. // --------------------------------------------------------------------
  353. /**
  354. * Compile header information
  355. *
  356. * Lists HTTP headers
  357. *
  358. * @return string
  359. */
  360. protected function _compile_http_headers()
  361. {
  362. $output = "\n\n";
  363. $output .= '<fieldset id="ci_profiler_http_headers" style="border:1px solid #000;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';
  364. $output .= "\n";
  365. $output .= '<legend style="color:#000;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_headers').'&nbsp;&nbsp;(<span style="cursor: pointer;" onclick="var s=document.getElementById(\'ci_profiler_httpheaders_table\').style;s.display=s.display==\'none\'?\'\':\'none\';this.innerHTML=this.innerHTML==\''.$this->CI->lang->line('profiler_section_show').'\'?\''.$this->CI->lang->line('profiler_section_hide').'\':\''.$this->CI->lang->line('profiler_section_show').'\';">'.$this->CI->lang->line('profiler_section_show').'</span>)</legend>';
  366. $output .= "\n";
  367. $output .= "\n\n<table style='width:100%;display:none' id='ci_profiler_httpheaders_table'>\n";
  368. foreach (array('HTTP_ACCEPT', 'HTTP_USER_AGENT', 'HTTP_CONNECTION', 'SERVER_PORT', 'SERVER_NAME', 'REMOTE_ADDR', 'SERVER_SOFTWARE', 'HTTP_ACCEPT_LANGUAGE', 'SCRIPT_NAME', 'REQUEST_METHOD',' HTTP_HOST', 'REMOTE_HOST', 'CONTENT_TYPE', 'SERVER_PROTOCOL', 'QUERY_STRING', 'HTTP_ACCEPT_ENCODING', 'HTTP_X_FORWARDED_FOR') as $header)
  369. {
  370. $val = (isset($_SERVER[$header])) ? $_SERVER[$header] : '';
  371. $output .= "<tr><td style='vertical-align: top;width:50%;padding:5px;color:#900;background-color:#ddd;'>".$header."&nbsp;&nbsp;</td><td style='width:50%;padding:5px;color:#000;background-color:#ddd;'>".$val."</td></tr>\n";
  372. }
  373. $output .= "</table>\n";
  374. $output .= "</fieldset>";
  375. return $output;
  376. }
  377. // --------------------------------------------------------------------
  378. /**
  379. * Compile config information
  380. *
  381. * Lists developer config variables
  382. *
  383. * @return string
  384. */
  385. protected function _compile_config()
  386. {
  387. $output = "\n\n";
  388. $output .= '<fieldset id="ci_profiler_config" style="border:1px solid #000;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';
  389. $output .= "\n";
  390. $output .= '<legend style="color:#000;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_config').'&nbsp;&nbsp;(<span style="cursor: pointer;" onclick="var s=document.getElementById(\'ci_profiler_config_table\').style;s.display=s.display==\'none\'?\'\':\'none\';this.innerHTML=this.innerHTML==\''.$this->CI->lang->line('profiler_section_show').'\'?\''.$this->CI->lang->line('profiler_section_hide').'\':\''.$this->CI->lang->line('profiler_section_show').'\';">'.$this->CI->lang->line('profiler_section_show').'</span>)</legend>';
  391. $output .= "\n";
  392. $output .= "\n\n<table style='width:100%; display:none' id='ci_profiler_config_table'>\n";
  393. foreach ($this->CI->config->config as $config=>$val)
  394. {
  395. if (is_array($val))
  396. {
  397. $val = print_r($val, TRUE);
  398. }
  399. $output .= "<tr><td style='padding:5px; vertical-align: top;color:#900;background-color:#ddd;'>".$config."&nbsp;&nbsp;</td><td style='padding:5px; color:#000;background-color:#ddd;'>".htmlspecialchars($val)."</td></tr>\n";
  400. }
  401. $output .= "</table>\n";
  402. $output .= "</fieldset>";
  403. return $output;
  404. }
  405. // --------------------------------------------------------------------
  406. /**
  407. * Compile session userdata
  408. *
  409. * @return string
  410. */
  411. private function _compile_session_data()
  412. {
  413. if ( ! isset($this->CI->session))
  414. {
  415. return;
  416. }
  417. $output = '<fieldset id="ci_profiler_csession" style="border:1px solid #000;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';
  418. $output .= '<legend style="color:#000;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_session_data').'&nbsp;&nbsp;(<span style="cursor: pointer;" onclick="var s=document.getElementById(\'ci_profiler_session_data\').style;s.display=s.display==\'none\'?\'\':\'none\';this.innerHTML=this.innerHTML==\''.$this->CI->lang->line('profiler_section_show').'\'?\''.$this->CI->lang->line('profiler_section_hide').'\':\''.$this->CI->lang->line('profiler_section_show').'\';">'.$this->CI->lang->line('profiler_section_show').'</span>)</legend>';
  419. $output .= "<table style='width:100%;display:none' id='ci_profiler_session_data'>";
  420. foreach ($this->CI->session->all_userdata() as $key => $val)
  421. {
  422. if (is_array($val))
  423. {
  424. $val = print_r($val, TRUE);
  425. }
  426. $output .= "<tr><td style='padding:5px; vertical-align: top;color:#900;background-color:#ddd;'>".$key."&nbsp;&nbsp;</td><td style='padding:5px; color:#000;background-color:#ddd;'>".htmlspecialchars($val)."</td></tr>\n";
  427. }
  428. $output .= '</table>';
  429. $output .= "</fieldset>";
  430. return $output;
  431. }
  432. // --------------------------------------------------------------------
  433. /**
  434. * Run the Profiler
  435. *
  436. * @return string
  437. */
  438. public function run()
  439. {
  440. $output = "<div id='codeigniter_profiler' style='clear:both;background-color:#fff;padding:10px;'>";
  441. $fields_displayed = 0;
  442. foreach ($this->_available_sections as $section)
  443. {
  444. if ($this->_compile_{$section} !== FALSE)
  445. {
  446. $func = "_compile_{$section}";
  447. $output .= $this->{$func}();
  448. $fields_displayed++;
  449. }
  450. }
  451. if ($fields_displayed == 0)
  452. {
  453. $output .= '<p style="border:1px solid #5a0099;padding:10px;margin:20px 0;background-color:#eee">'.$this->CI->lang->line('profiler_no_profiles').'</p>';
  454. }
  455. $output .= '</div>';
  456. return $output;
  457. }
  458. }
  459. // END CI_Profiler class
  460. /* End of file Profiler.php */
  461. /* Location: ./system/libraries/Profiler.php */