blob: da1fff19b362f76d188ea1ebeb774a1d43619b9b [file] [log] [blame]
Derek Jones0b59f272008-05-13 04:22:33 +00001<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
Derek Allardc2f90e22007-04-03 11:17:44 +00002/**
Derek Allardd2df9bc2007-04-15 17:41:17 +00003 * CodeIgniter
Derek Allardc2f90e22007-04-03 11:17:44 +00004 *
5 * An open source application development framework for PHP 4.3.2 or newer
6 *
7 * @package CodeIgniter
Derek Allard3d879d52008-01-18 19:41:32 +00008 * @author ExpressionEngine Dev Team
Derek Allardd2df9bc2007-04-15 17:41:17 +00009 * @copyright Copyright (c) 2006, EllisLab, Inc.
Derek Jones7a9193a2008-01-21 18:39:20 +000010 * @license http://codeigniter.com/user_guide/license.html
11 * @link http://codeigniter.com
Derek Allardc2f90e22007-04-03 11:17:44 +000012 * @since Version 1.0
13 * @filesource
14 */
15
16// ------------------------------------------------------------------------
17
18/**
Derek Allardd2df9bc2007-04-15 17:41:17 +000019 * CodeIgniter Profiler Class
Derek Allardc2f90e22007-04-03 11:17:44 +000020 *
21 * This class enables you to display benchmark, query, and other data
22 * in order to help with debugging and optimization.
23 *
24 * Note: At some point it would be good to move all the HTML in this class
25 * into a set of template files in order to allow customization.
26 *
27 * @package CodeIgniter
28 * @subpackage Libraries
29 * @category Libraries
Derek Allard3d879d52008-01-18 19:41:32 +000030 * @author ExpressionEngine Dev Team
Derek Jones7a9193a2008-01-21 18:39:20 +000031 * @link http://codeigniter.com/user_guide/general/profiling.html
Derek Allardc2f90e22007-04-03 11:17:44 +000032 */
33class CI_Profiler {
34
35 var $CI;
36
37 function CI_Profiler()
38 {
39 $this->CI =& get_instance();
40 $this->CI->load->language('profiler');
41 }
42
43 // --------------------------------------------------------------------
44
45 /**
46 * Auto Profiler
47 *
48 * This function cycles through the entire array of mark points and
49 * matches any two points that are named identically (ending in "_start"
50 * and "_end" respectively). It then compiles the execution times for
51 * all points and returns it as an array
52 *
53 * @access private
54 * @return array
55 */
56 function _compile_benchmarks()
57 {
58 $profile = array();
59 foreach ($this->CI->benchmark->marker as $key => $val)
60 {
61 // We match the "end" marker so that the list ends
62 // up in the order that it was defined
63 if (preg_match("/(.+?)_end/i", $key, $match))
64 {
65 if (isset($this->CI->benchmark->marker[$match[1].'_end']) AND isset($this->CI->benchmark->marker[$match[1].'_start']))
66 {
67 $profile[$match[1]] = $this->CI->benchmark->elapsed_time($match[1].'_start', $key);
68 }
69 }
70 }
71
72 // Build a table containing the profile data.
73 // Note: At some point we should turn this into a template that can
74 // be modified. We also might want to make this data available to be logged
75
76 $output = "\n\n";
77 $output .= '<fieldset style="border:1px solid #990000;padding:6px 10px 10px 10px;margin:0 0 20px 0;background-color:#eee">';
78 $output .= "\n";
79 $output .= '<legend style="color:#990000;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_benchmarks').'&nbsp;&nbsp;</legend>';
80 $output .= "\n";
81 $output .= "\n\n<table cellpadding='4' cellspacing='1' border='0' width='100%'>\n";
82
83 foreach ($profile as $key => $val)
84 {
85 $key = ucwords(str_replace(array('_', '-'), ' ', $key));
86 $output .= "<tr><td width='50%' style='color:#000;font-weight:bold;background-color:#ddd;'>".$key."&nbsp;&nbsp;</td><td width='50%' style='color:#990000;font-weight:normal;background-color:#ddd;'>".$val."</td></tr>\n";
87 }
88
89 $output .= "</table>\n";
90 $output .= "</fieldset>";
91
92 return $output;
93 }
94
95 // --------------------------------------------------------------------
96
97 /**
98 * Compile Queries
99 *
100 * @access private
101 * @return string
102 */
103 function _compile_queries()
104 {
105 $output = "\n\n";
106 $output .= '<fieldset style="border:1px solid #0000FF;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';
107 $output .= "\n";
Derek Allardc2f90e22007-04-03 11:17:44 +0000108
Derek Jones0b59f272008-05-13 04:22:33 +0000109 if ( ! class_exists('CI_DB_driver'))
Derek Allardc2f90e22007-04-03 11:17:44 +0000110 {
Derek Jones56e9fa52008-01-23 17:26:37 +0000111 $output .= '<legend style="color:#0000FF;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_queries').'&nbsp;&nbsp;</legend>';
112 $output .= "\n";
113 $output .= "\n\n<table cellpadding='4' cellspacing='1' border='0' width='100%'>\n";
114 $output .="<tr><td width='100%' style='color:#0000FF;font-weight:normal;background-color:#eee;'>".$this->CI->lang->line('profiler_no_db')."</td></tr>\n";
Derek Allardc2f90e22007-04-03 11:17:44 +0000115 }
116 else
117 {
Derek Jones56e9fa52008-01-23 17:26:37 +0000118 $output .= '<legend style="color:#0000FF;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_queries').' ('.count($this->CI->db->queries).')&nbsp;&nbsp;</legend>';
119 $output .= "\n";
120 $output .= "\n\n<table cellpadding='4' cellspacing='1' border='0' width='100%'>\n";
121
Derek Allardc2f90e22007-04-03 11:17:44 +0000122 if (count($this->CI->db->queries) == 0)
123 {
Derek Jones56e9fa52008-01-23 17:26:37 +0000124 $output .= "<tr><td width='100%' style='color:#0000FF;font-weight:normal;background-color:#eee;'>".$this->CI->lang->line('profiler_no_queries')."</td></tr>\n";
Derek Allardc2f90e22007-04-03 11:17:44 +0000125 }
126 else
127 {
Derek Jonesb35c3f52008-02-08 20:48:23 +0000128 $highlight = array('SELECT', 'FROM', 'WHERE', 'AND', 'LEFT JOIN', 'ORDER BY', 'LIMIT', 'INSERT', 'INTO', 'VALUES', 'UPDATE', 'OR');
Derek Jones56e9fa52008-01-23 17:26:37 +0000129
130 foreach ($this->CI->db->queries as $key => $val)
Derek Allardc2f90e22007-04-03 11:17:44 +0000131 {
Derek Jones56e9fa52008-01-23 17:26:37 +0000132 $val = htmlspecialchars($val, ENT_QUOTES);
133 $time = number_format($this->CI->db->query_times[$key], 4);
134
135 foreach ($highlight as $bold)
136 {
137 $val = str_replace($bold, '<strong>'.$bold.'</strong>', $val);
138 }
139
140 $output .= "<tr><td width='1%' valign='top' style='color:#990000;font-weight:normal;background-color:#ddd;'>".$time."&nbsp;&nbsp;</td><td style='color:#000;font-weight:normal;background-color:#ddd;'>".$val."</td></tr>\n";
141 }
Derek Allardc2f90e22007-04-03 11:17:44 +0000142 }
143 }
144
Derek Jones56e9fa52008-01-23 17:26:37 +0000145 $output .= "</table>\n";
146 $output .= "</fieldset>";
Derek Allardc2f90e22007-04-03 11:17:44 +0000147
148 return $output;
149 }
Derek Jones56e9fa52008-01-23 17:26:37 +0000150
Derek Allardc2f90e22007-04-03 11:17:44 +0000151
152 // --------------------------------------------------------------------
153
154 /**
Derek Jonesd087ef82008-01-18 21:41:23 +0000155 * Compile $_GET Data
156 *
157 * @access private
158 * @return string
159 */
160 function _compile_get()
161 {
162 $output = "\n\n";
163 $output .= '<fieldset style="border:1px solid #cd6e00;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';
164 $output .= "\n";
165 $output .= '<legend style="color:#cd6e00;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_get_data').'&nbsp;&nbsp;</legend>';
166 $output .= "\n";
167
168 if (count($_GET) == 0)
169 {
170 $output .= "<div style='color:#cd6e00;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->lang->line('profiler_no_get')."</div>";
171 }
172 else
173 {
174 $output .= "\n\n<table cellpadding='4' cellspacing='1' border='0' width='100%'>\n";
175
176 foreach ($_GET as $key => $val)
177 {
Derek Jones0b59f272008-05-13 04:22:33 +0000178 if ( ! is_numeric($key))
Derek Jonesd087ef82008-01-18 21:41:23 +0000179 {
180 $key = "'".$key."'";
181 }
182
183 $output .= "<tr><td width='50%' style='color:#000;background-color:#ddd;'>&#36;_GET[".$key."]&nbsp;&nbsp; </td><td width='50%' style='color:#cd6e00;font-weight:normal;background-color:#ddd;'>";
184 if (is_array($val))
185 {
186 $output .= "<pre>" . htmlspecialchars(stripslashes(print_r($val, true))) . "</pre>";
187 }
188 else
189 {
190 $output .= htmlspecialchars(stripslashes($val));
191 }
192 $output .= "</td></tr>\n";
193 }
194
195 $output .= "</table>\n";
196 }
197 $output .= "</fieldset>";
198
199 return $output;
200 }
201
202 // --------------------------------------------------------------------
203
204 /**
Derek Allardc2f90e22007-04-03 11:17:44 +0000205 * Compile $_POST Data
206 *
207 * @access private
208 * @return string
209 */
210 function _compile_post()
211 {
212 $output = "\n\n";
213 $output .= '<fieldset style="border:1px solid #009900;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';
214 $output .= "\n";
215 $output .= '<legend style="color:#009900;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_post_data').'&nbsp;&nbsp;</legend>';
216 $output .= "\n";
217
218 if (count($_POST) == 0)
219 {
220 $output .= "<div style='color:#009900;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->lang->line('profiler_no_post')."</div>";
221 }
222 else
223 {
224 $output .= "\n\n<table cellpadding='4' cellspacing='1' border='0' width='100%'>\n";
225
226 foreach ($_POST as $key => $val)
227 {
Derek Jones0b59f272008-05-13 04:22:33 +0000228 if ( ! is_numeric($key))
Derek Allardc2f90e22007-04-03 11:17:44 +0000229 {
230 $key = "'".$key."'";
231 }
232
233// $output .= "<tr><td width='50%' style='color:#000;background-color:#ddd;'>&#36;_POST[".$key."]&nbsp;&nbsp;</td><td width='50%' style='color:#009900;font-weight:normal;background-color:#ddd;'>".htmlspecialchars(stripslashes($val))."</td></tr>\n";
Derek Jones9687c492007-07-11 21:43:23 +0000234 $output .= "<tr><td width='50%' style='color:#000;background-color:#ddd;'>&#36;_POST[".$key."]&nbsp;&nbsp; </td><td width='50%' style='color:#009900;font-weight:normal;background-color:#ddd;'>";
Derek Allardc2f90e22007-04-03 11:17:44 +0000235 if (is_array($val))
236 {
237 $output .= "<pre>" . htmlspecialchars(stripslashes(print_r($val, true))) . "</pre>";
238 }
239 else
240 {
241 $output .= htmlspecialchars(stripslashes($val));
242 }
243 $output .= "</td></tr>\n";
244 }
245
246 $output .= "</table>\n";
247 }
248 $output .= "</fieldset>";
249
250 return $output;
251 }
252
253 // --------------------------------------------------------------------
254
255 /**
Derek Jonesd087ef82008-01-18 21:41:23 +0000256 * Show query string
257 *
258 * @access private
259 * @return string
260 */
261 function _compile_uri_string()
262 {
263 $output = "\n\n";
264 $output .= '<fieldset style="border:1px solid #000;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';
265 $output .= "\n";
266 $output .= '<legend style="color:#000;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_uri_string').'&nbsp;&nbsp;</legend>';
267 $output .= "\n";
268
269 if ($this->CI->uri->uri_string == '')
270 {
271 $output .= "<div style='color:#000;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->lang->line('profiler_no_uri')."</div>";
272 }
273 else
274 {
275 $output .= "<div style='color:#000;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->uri->uri_string."</div>";
276 }
277
278 $output .= "</fieldset>";
279
280 return $output;
281 }
282
283 // --------------------------------------------------------------------
284
285 /**
286 * Compile memory usage
287 *
288 * Display total used memory
289 *
290 * @access public
291 * @return string
292 */
293 function _compile_memory_usage()
294 {
295 $output = "\n\n";
296 $output .= '<fieldset style="border:1px solid #000;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';
297 $output .= "\n";
298 $output .= '<legend style="color:#000;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_memory_usage').'&nbsp;&nbsp;</legend>';
299 $output .= "\n";
300
301 if (function_exists('memory_get_usage') && ($usage = memory_get_usage()) != '')
302 {
303 $output .= "<div style='color:#000;font-weight:normal;padding:4px 0 4px 0'>".number_format($usage).' bytes</div>';
304 }
305 else
306 {
307 $output .= "<div style='color:#000;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->lang->line('profiler_no_memory_usage')."</div>";
308 }
309
310 $output .= "</fieldset>";
311
312 return $output;
313 }
314
315 // --------------------------------------------------------------------
316
317 /**
Derek Allardc2f90e22007-04-03 11:17:44 +0000318 * Run the Profiler
319 *
320 * @access private
321 * @return string
322 */
Derek Allard31438fe2008-01-29 01:07:06 +0000323 function run()
Derek Allardc2f90e22007-04-03 11:17:44 +0000324 {
325 $output = '<br clear="all" />';
326 $output .= "<div style='background-color:#fff;padding:10px;'>";
Derek Jonesd087ef82008-01-18 21:41:23 +0000327
328 $output .= $this->_compile_memory_usage();
329 $output .= $this->_compile_benchmarks();
330 $output .= $this->_compile_uri_string();
331 $output .= $this->_compile_get();
Derek Allardc2f90e22007-04-03 11:17:44 +0000332 $output .= $this->_compile_post();
333 $output .= $this->_compile_queries();
334
335 $output .= '</div>';
336
337 return $output;
338 }
339
340}
341
342// END CI_Profiler class
Derek Jones0b59f272008-05-13 04:22:33 +0000343
344/* End of file Profiler.php */
Derek Jonesa3ffbbb2008-05-11 18:18:29 +0000345/* Location: ./system/libraries/Profiler.php */