PageRenderTime 47ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/application/libraries/Profiler.php

https://github.com/HipsterJazzbo/CI-Instant-Admin
PHP | 527 lines | 298 code | 89 blank | 140 comment | 41 complexity | 305c6f5b449b62df9a8e19a038f5a85b 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. var $CI;
  33. protected $_available_sections = array(
  34. 'benchmarks',
  35. 'get',
  36. 'memory_usage',
  37. 'post',
  38. 'uri_string',
  39. 'controller_info',
  40. 'queries',
  41. 'http_headers',
  42. 'config',
  43. 'files',
  44. 'console',
  45. 'userdata'
  46. );
  47. protected $_sections = array(); // Stores _compile_x() results
  48. // --------------------------------------------------------------------
  49. public function __construct($config = array())
  50. {
  51. $this->CI =& get_instance();
  52. $this->CI->load->language('profiler');
  53. // default all sections to display
  54. foreach ($this->_available_sections as $section)
  55. {
  56. if ( ! isset($config[$section]))
  57. {
  58. $this->_compile_{$section} = TRUE;
  59. }
  60. }
  61. // Make sure the Console is loaded.
  62. if (!class_exists('Console'))
  63. {
  64. $this->CI->load->library('Console');
  65. }
  66. $this->set_sections($config);
  67. }
  68. // --------------------------------------------------------------------
  69. /**
  70. * Set Sections
  71. *
  72. * Sets the private _compile_* properties to enable/disable Profiler sections
  73. *
  74. * @param mixed
  75. * @return void
  76. */
  77. public function set_sections($config)
  78. {
  79. foreach ($config as $method => $enable)
  80. {
  81. if (in_array($method, $this->_available_sections))
  82. {
  83. $this->_compile_{$method} = ($enable !== FALSE) ? TRUE : FALSE;
  84. }
  85. }
  86. }
  87. // --------------------------------------------------------------------
  88. /**
  89. * Auto Profiler
  90. *
  91. * This function cycles through the entire array of mark points and
  92. * matches any two points that are named identically (ending in "_start"
  93. * and "_end" respectively). It then compiles the execution times for
  94. * all points and returns it as an array
  95. *
  96. * @return array
  97. */
  98. protected function _compile_benchmarks()
  99. {
  100. $profile = array();
  101. $output = array();
  102. foreach ($this->CI->benchmark->marker as $key => $val)
  103. {
  104. // We match the "end" marker so that the list ends
  105. // up in the order that it was defined
  106. if (preg_match("/(.+?)_end/i", $key, $match))
  107. {
  108. if (isset($this->CI->benchmark->marker[$match[1].'_end']) AND isset($this->CI->benchmark->marker[$match[1].'_start']))
  109. {
  110. $profile[$match[1]] = $this->CI->benchmark->elapsed_time($match[1].'_start', $key);
  111. }
  112. }
  113. }
  114. // Build a table containing the profile data.
  115. // Note: At some point we might want to make this data available to be logged.
  116. foreach ($profile as $key => $val)
  117. {
  118. $key = ucwords(str_replace(array('_', '-'), ' ', $key));
  119. $output[$key] = $val;
  120. }
  121. return $output;
  122. }
  123. // --------------------------------------------------------------------
  124. /**
  125. * Compile Queries
  126. *
  127. * @return string
  128. */
  129. protected function _compile_queries()
  130. {
  131. $dbs = array();
  132. $output = array();
  133. // Let's determine which databases are currently connected to
  134. foreach (get_object_vars($this->CI) as $CI_object)
  135. {
  136. if (is_object($CI_object) && is_subclass_of(get_class($CI_object), 'CI_DB') )
  137. {
  138. $dbs[] = $CI_object;
  139. }
  140. }
  141. if (count($dbs) == 0)
  142. {
  143. return $this->CI->lang->line('profiler_no_db');
  144. }
  145. // Load the text helper so we can highlight the SQL
  146. $this->CI->load->helper('text');
  147. // Key words we want bolded
  148. $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', '(', ')');
  149. foreach ($dbs as $db)
  150. {
  151. if (count($db->queries) == 0)
  152. {
  153. $output = $this->CI->lang->line('profiler_no_queries');
  154. }
  155. else
  156. {
  157. foreach ($db->queries as $key => $val)
  158. {
  159. $time = number_format($db->query_times[$key], 4);
  160. /*
  161. $val = highlight_code($val, ENT_QUOTES);
  162. foreach ($highlight as $bold)
  163. {
  164. $val = str_replace($bold, '<strong>'.$bold.'</strong>', $val);
  165. }
  166. */
  167. $output[$time] = $val;
  168. }
  169. }
  170. }
  171. return $output;
  172. }
  173. // --------------------------------------------------------------------
  174. /**
  175. * Compile $_GET Data
  176. *
  177. * @return string
  178. */
  179. protected function _compile_get()
  180. {
  181. $output = array();
  182. if (count($_GET) == 0)
  183. {
  184. $output = $this->CI->lang->line('profiler_no_get');
  185. }
  186. else
  187. {
  188. foreach ($_GET as $key => $val)
  189. {
  190. if ( ! is_numeric($key))
  191. {
  192. $key = "'".$key."'";
  193. }
  194. $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;'>";
  195. if (is_array($val))
  196. {
  197. $output['&#36;_GET['. $key .']'] = "<pre>" . htmlspecialchars(stripslashes(print_r($val, true))) . "</pre>";
  198. }
  199. else
  200. {
  201. $output['&#36;_GET['. $key .']'] = htmlspecialchars(stripslashes($val));
  202. }
  203. }
  204. }
  205. return $output;
  206. }
  207. // --------------------------------------------------------------------
  208. /**
  209. * Compile $_POST Data
  210. *
  211. * @return string
  212. */
  213. protected function _compile_post()
  214. {
  215. $output = array();
  216. if (count($_POST) == 0)
  217. {
  218. $output = $this->CI->lang->line('profiler_no_post');
  219. }
  220. else
  221. {
  222. foreach ($_POST as $key => $val)
  223. {
  224. if ( ! is_numeric($key))
  225. {
  226. $key = "'".$key."'";
  227. }
  228. if (is_array($val))
  229. {
  230. $output['&#36;_POST['. $key .']'] = '<pre>'. htmlspecialchars(stripslashes(print_r($val, TRUE))) . '</pre>';
  231. }
  232. else
  233. {
  234. $output['&#36;_POST['. $key .']'] = htmlspecialchars(stripslashes($val));
  235. }
  236. }
  237. }
  238. return $output;
  239. }
  240. // --------------------------------------------------------------------
  241. /**
  242. * Show query string
  243. *
  244. * @return string
  245. */
  246. protected function _compile_uri_string()
  247. {
  248. if ($this->CI->uri->uri_string == '')
  249. {
  250. $output = $this->CI->lang->line('profiler_no_uri');
  251. }
  252. else
  253. {
  254. $output = $this->CI->uri->uri_string;
  255. }
  256. return $output;
  257. }
  258. // --------------------------------------------------------------------
  259. /**
  260. * Show the controller and function that were called
  261. *
  262. * @return string
  263. */
  264. protected function _compile_controller_info()
  265. {
  266. $output = $this->CI->router->fetch_class()."/".$this->CI->router->fetch_method();
  267. return $output;
  268. }
  269. // --------------------------------------------------------------------
  270. /**
  271. * Compile memory usage
  272. *
  273. * Display total used memory
  274. *
  275. * @return string
  276. */
  277. protected function _compile_memory_usage()
  278. {
  279. if (function_exists('memory_get_usage') && ($usage = memory_get_usage()) != '')
  280. {
  281. $output = number_format($usage) .' bytes';
  282. }
  283. else
  284. {
  285. $output = $this->CI->lang->line('profiler_no_memory_usage');
  286. }
  287. return $output;
  288. }
  289. // --------------------------------------------------------------------
  290. /**
  291. * Compile header information
  292. *
  293. * Lists HTTP headers
  294. *
  295. * @return string
  296. */
  297. protected function _compile_http_headers()
  298. {
  299. $output = array();
  300. 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)
  301. {
  302. $val = (isset($_SERVER[$header])) ? $_SERVER[$header] : '';
  303. $output[$header] = $val;
  304. }
  305. return $output;
  306. }
  307. // --------------------------------------------------------------------
  308. /**
  309. * Compile config information
  310. *
  311. * Lists developer config variables
  312. *
  313. * @return string
  314. */
  315. protected function _compile_config()
  316. {
  317. $output = array();
  318. foreach ($this->CI->config->config as $config=>$val)
  319. {
  320. if (is_array($val))
  321. {
  322. $val = print_r($val, TRUE);
  323. }
  324. $output[$config] = htmlspecialchars($val);
  325. }
  326. return $output;
  327. }
  328. // --------------------------------------------------------------------
  329. public function _compile_files()
  330. {
  331. $files = get_included_files();
  332. sort($files);
  333. return $files;
  334. }
  335. //--------------------------------------------------------------------
  336. public function _compile_console()
  337. {
  338. $logs = Console::get_logs();
  339. if ($logs['console'])
  340. {
  341. foreach ($logs['console'] as $key => $log)
  342. {
  343. if ($log['type'] == 'log')
  344. {
  345. $logs['console'][$key]['data'] = print_r($log['data'], true);
  346. }
  347. elseif ($log['type'] == 'memory')
  348. {
  349. $logs['console'][$key]['data'] = $this->get_file_size($log['data']);
  350. }
  351. }
  352. }
  353. //echo '<pre>'; print_r($logs); echo '</pre>';
  354. return $logs;
  355. }
  356. //--------------------------------------------------------------------
  357. function _compile_userdata()
  358. {
  359. $output = array();
  360. $compiled_userdata = $this->CI->session->all_userdata();
  361. if (count($compiled_userdata))
  362. {
  363. foreach ($compiled_userdata as $key => $val)
  364. {
  365. if (is_numeric($key))
  366. {
  367. $output[$key] = "'$val'";
  368. }
  369. if (is_array($val))
  370. {
  371. $output[$key] = htmlspecialchars(stripslashes(print_r($val, true)));
  372. }
  373. else
  374. {
  375. $output[$key] = htmlspecialchars(stripslashes($val));
  376. }
  377. }
  378. }
  379. return $output;
  380. }
  381. //--------------------------------------------------------------------
  382. public static function get_file_size($size, $retstring = null) {
  383. // adapted from code at http://aidanlister.com/repos/v/function.size_readable.php
  384. $sizes = array('bytes', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
  385. if ($retstring === null) { $retstring = '%01.2f %s'; }
  386. $lastsizestring = end($sizes);
  387. foreach ($sizes as $sizestring) {
  388. if ($size < 1024) { break; }
  389. if ($sizestring != $lastsizestring) { $size /= 1024; }
  390. }
  391. if ($sizestring == $sizes[0]) { $retstring = '%01d %s'; } // Bytes aren't normally fractional
  392. return sprintf($retstring, $size, $sizestring);
  393. }
  394. //--------------------------------------------------------------------
  395. /**
  396. * Run the Profiler
  397. *
  398. * @return string
  399. */
  400. public function run()
  401. {
  402. $this->CI->load->helper('language');
  403. $fields_displayed = 0;
  404. foreach ($this->_available_sections as $section)
  405. {
  406. if ($this->_compile_{$section} !== FALSE)
  407. {
  408. $func = "_compile_{$section}";
  409. $this->_sections[$section] = $this->{$func}();
  410. $fields_displayed++;
  411. }
  412. }
  413. // Has the user created an override in application/views?
  414. if (is_file(APPPATH .'views/profiler_template'.EXT))
  415. {
  416. $output = $this->CI->load->view('profiler_template', array('sections' => $this->_sections), true);
  417. }
  418. else
  419. {
  420. // Load the view from system/views
  421. $orig_view_path = $this->CI->load->_ci_view_path;
  422. $this->CI->load->_ci_view_path = BASEPATH .'views/';
  423. //echo $this->CI->load->_ci_view_path;
  424. $output = $this->CI->load->_ci_load(array(
  425. '_ci_view' => 'profiler_template',
  426. '_ci_vars' => array('sections' => $this->_sections),
  427. '_ci_return' => true,
  428. ));
  429. $this->CI->load->_ci_view_path = $orig_view_path;
  430. }
  431. return $output;
  432. }
  433. }
  434. // END CI_Profiler class
  435. //--------------------------------------------------------------------
  436. /* End of file Profiler.php */
  437. /* Location: ./system/libraries/Profiler.php */