Overview

Namespaces

  • None
  • Rundiz
    • Profiler

Classes

  • Rundiz\Profiler\Console
  • Rundiz\Profiler\Profiler
  • Rundiz\Profiler\ProfilerBase

Functions

  • rdProfilerLoadCss
  • rdProfilerLoadJs
  • Overview
  • Namespace
  • Class
  1: <?php
  2: /** 
  3:  * Rundiz Profiler
  4:  * 
  5:  * @license http://opensource.org/licenses/MIT
  6:  */
  7: 
  8: 
  9: namespace Rundiz\Profiler;
 10: 
 11: /**
 12:  * Profiler class.
 13:  * 
 14:  * This class works as processing the data for profiler such as gather things (input, file, sessions), get micro time.<br>
 15:  * This class also display the profiling result and dump the data for check or tests.
 16:  * 
 17:  * @package Rundiz\Profiler
 18:  * @author Vee W.
 19:  */
 20: class Profiler extends \Rundiz\Profiler\ProfilerBase
 21: {
 22: 
 23: 
 24:     /**
 25:      * console class chaining.
 26:      * 
 27:      * @var \Rundiz\Profiler\Console for access console class
 28:      */
 29:     public $Console;
 30: 
 31: 
 32:     /**
 33:      * class constructor.
 34:      */
 35:     public function __construct() {
 36:         $this->start_time = $this->getMicrotime(true);
 37: 
 38:         if (!class_exists('\\Rundiz\\Profiler\\Console')) {
 39:             require_once __DIR__.DIRECTORY_SEPARATOR.'Console.php';
 40:         }
 41:         $this->Console = new \Rundiz\Profiler\Console($this);
 42:     }// __construct
 43: 
 44: 
 45:     /**
 46:      * Count total log type in the "Logs" section.
 47:      * 
 48:      * @param string $logtype Accept debug, info, notice, warning, error, critical, alert, emergency. referrer: http://www.php-fig.org/psr/psr-3/
 49:      * @return integer Return counted total log type in the "Logs" section.
 50:      */
 51:     public function countTotalLogType($logtype)
 52:     {
 53:         $count = 0;
 54: 
 55:         if (isset($this->log_sections['Logs']) && is_array($this->log_sections['Logs'])) {
 56:             foreach ($this->log_sections['Logs'] as $item) {
 57:                 if (isset($item['logtype']) && $item['logtype'] == $logtype) {
 58:                     $count++;
 59:                 }
 60:             }// endforeach;
 61:             unset($item);
 62:         }
 63: 
 64:         return $count;
 65:     }// countTotalLogType
 66: 
 67: 
 68:     /**
 69:      * display the profiler data results.
 70:      * 
 71:      * @return string return the profiler result in html.
 72:      */
 73:     public function display($dbh = '', $display_db_function = '')
 74:     {
 75:         $this->gatherAll();
 76: 
 77:         // return display views.
 78:         ob_start();
 79:         require __DIR__.DIRECTORY_SEPARATOR.'views'.DIRECTORY_SEPARATOR.'display.php';
 80:         $output = ob_get_contents();
 81:         ob_end_clean();
 82:         return $output;
 83:     }// display
 84: 
 85: 
 86:     /**
 87:      * for checking only.
 88:      * 
 89:      * @return array
 90:      */
 91:     public function dumptest()
 92:     {
 93:         return [
 94:             'log_sections' => $this->log_sections, 
 95:             'start_time' => $this->start_time, 
 96:             'end_time' => $this->end_time,
 97:             'max_memory_usage' => $this->max_memory_usage,
 98:         ];
 99:     }// dumptest
100: 
101: 
102:     /**
103:      * gather all data before call display. this can be done automatically if you just call display().
104:      */
105:     public function gatherAll()
106:     {
107:         // don't call getMicrotime and memory_get_peak_usage in display page because it can increase too much.
108:         // at this point the application process should end already. push these number into class's property instead.
109:         $this->end_time = $this->getMicrotime();
110:         $this->max_memory_usage = memory_get_peak_usage();
111: 
112:         $this->gatherFiles();
113:         $this->gatherInputGet();
114:         $this->gatherInputPost();
115:         $this->gatherInputSession();
116:     }// gatherAll
117: 
118: 
119:     /**
120:      * gather included files and its size.
121:      */
122:     private function gatherFiles()
123:     {
124:         if (!array_key_exists('Files', $this->log_sections)) {
125:             return ;
126:         }
127: 
128:         $files = get_included_files();
129:         $section_data_array = [];
130:         $total_size = 0;
131:         $largest_size = 0;
132: 
133:         if (is_array($files)) {
134:             foreach ($files as $file) {
135:                 $size = filesize($file);
136:                 $section_data_array[] = [
137:                     'data' => $file,
138:                     'size' => $size,
139:                 ];
140:                 $total_size = bcadd($total_size, $size);
141: 
142:                 if ($size > $largest_size) {
143:                     $largest_size = $size;
144:                 }
145:             }// endforeach;
146:             unset($file, $size);
147:         }
148: 
149:         $section_data_array['total_size'] = $total_size;
150:         $section_data_array['largest_size'] = $largest_size;
151:         unset($largest_size, $total_size);
152: 
153:         $this->log_sections['Files'] = $section_data_array;
154:         unset($files, $section_data_array);
155:     }// gatherFiles
156: 
157: 
158:     /**
159:      * gather input get
160:      */
161:     private function gatherInputGet()
162:     {
163:         if (!array_key_exists('Get', $this->log_sections)) {
164:             return ;
165:         }
166: 
167:         $section_data_array = [];
168: 
169:         if (isset($_GET) && is_array($_GET)) {
170:             foreach ($_GET as $name => $value) {
171:                 $section_data_array[] = [
172:                     'data' => $name,
173:                     'inputvalue' => $value,
174:                 ];
175:             }// endforeach;
176:             unset($name, $value);
177:         }
178: 
179:         $this->log_sections['Get'] = $section_data_array;
180:         unset($section_data_array);
181:     }// gatherInputGet
182: 
183: 
184:     /**
185:      * gather input post
186:      */
187:     private function gatherInputPost()
188:     {
189:         if (!array_key_exists('Post', $this->log_sections)) {
190:             return ;
191:         }
192: 
193:         $section_data_array = [];
194: 
195:         if (isset($_POST) && is_array($_POST)) {
196:             foreach ($_POST as $name => $value) {
197:                 $section_data_array[] = [
198:                     'data' => $name,
199:                     'inputvalue' => $value,
200:                 ];
201:             }// endforeach;
202:             unset($name, $value);
203:         }
204: 
205:         $this->log_sections['Post'] = $section_data_array;
206:         unset($section_data_array);
207:     }// gatherInputPost
208: 
209: 
210:     /**
211:      * gather input session
212:      */
213:     private function gatherInputSession()
214:     {
215:         if (!array_key_exists('Session', $this->log_sections)) {
216:             return ;
217:         }
218: 
219:         $section_data_array = [];
220: 
221:         if (isset($_SESSION) && is_array($_SESSION)) {
222:             foreach ($_SESSION as $name => $value) {
223:                 $section_data_array[] = [
224:                     'data' => $name,
225:                     'inputvalue' => $value,
226:                 ];
227:             }// endforeach;
228:             unset($name, $value);
229:         }
230: 
231:         $this->log_sections['Session'] = $section_data_array;
232:         unset($section_data_array);
233:     }// Session
234: 
235: 
236:     /**
237:      * get readable file size.<br>
238:      * copy from php quick profiler
239:      * 
240:      * @param int $size
241:      * @param string $retstring
242:      * @return string
243:      */
244:     public function getReadableFileSize($size, $retstring = null) {
245:         // adapted from code at http://aidanlister.com/repos/v/function.size_readable.php
246:         $sizes = ['bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
247: 
248:         if ($retstring === null) {
249:             $retstring = '%01.2f %s';
250:         }
251: 
252:         $lastsizestring = end($sizes);
253: 
254:         foreach ($sizes as $sizestring) {
255:             if ($size < 1024) {
256:                 break;
257:             }
258:             if ($sizestring != $lastsizestring) {
259:                 $size /= 1024;
260:             }
261:         }
262:         if ($sizestring == $sizes[0]) {
263:             $retstring = '%01d %s';
264:         } // Bytes aren't normally fractional
265:         return sprintf($retstring, $size, $sizestring);
266:     }// getReadableFileSize
267: 
268: 
269:     /**
270:      * get microtime.
271:      * 
272:      * @param boolean $at_start set to true if this microtime is get at the very beginning of the app. this can allow newer php version to use $_SERVER['REQUEST_TIME_FLOAT'];
273:      * @return float microtime in float.
274:      */
275:     public function getMicrotime($at_start = false)
276:     {
277:         if ($at_start === true && is_array($_SERVER) && array_key_exists('REQUEST_TIME_FLOAT', $_SERVER)) {
278:             return floatval($_SERVER['REQUEST_TIME_FLOAT']);
279:         }
280: 
281:         return floatval(microtime(true));
282:     }// getMicrotime
283: 
284: 
285:     /**
286:      * get readable time.<br>
287:      * copy from php quick profiler
288:      * 
289:      * @param integer $time
290:      * @return string
291:      */
292:     public function getReadableTime($time) {
293:         $ret = $time;
294:         $formatter = 0;
295:         $formats = ['ms', 's', 'm'];
296:         if ($time >= 1000 && $time < 60000) {
297:             $formatter = 1;
298:             $ret = ($time / 1000);
299:         }
300:         if ($time >= 60000) {
301:             $formatter = 2;
302:             $ret = ($time / 1000) / 60;
303:         }
304:         $ret = number_format($ret, 3, '.', '') . ' ' . $formats[$formatter];
305:         unset($formats, $formatter);
306:         return $ret;
307:     }// getReadableTime
308: 
309: 
310:     /**
311:      * Summary start and end of match key in a section.
312:      * 
313:      * @param string $section The section name.
314:      * @param string $matchKey The match key in that section.
315:      * @param integer $sectionKey The array index key of the section for check while displaying in the loop.
316:      * @return string Return the readable result if found 2 match key and can summary. Return empty string if not found.
317:      */
318:     public function summaryMatchKey($section, $matchKey, $sectionKey)
319:     {
320:         if (!is_string($section)) {
321:             $section = null;
322:         }
323: 
324:         if (!is_string($matchKey)) {
325:             $matchKey = null;
326:         }
327: 
328:         if (!is_numeric($sectionKey)) {
329:             $sectionKey = 0;
330:         }
331: 
332:         $output = '';
333: 
334:         if (isset($this->log_sections[$section]) && is_array($this->log_sections[$section]) && $matchKey !== null) {
335:             $matchKeyTime = [];
336:             $matchKeyMemory = [];
337: 
338:             foreach ($this->log_sections[$section] as $key => $item) {
339:                 if (isset($item['matchKey']) && $item['matchKey'] == $matchKey && $key <= $sectionKey) {
340:                     if (count($matchKeyMemory) >= 2 || count($matchKeyTime) >= 2) {
341:                         break;
342:                     }
343: 
344:                     if (isset($item['time'])) {
345:                         $matchKeyTime[] = $item['time'];
346:                     }
347: 
348:                     if (isset($item['memory'])) {
349:                         $matchKeyMemory[] = $item['memory'];
350:                     }
351:                 }
352:             }// endforeach;
353:             unset($item, $key);
354: 
355:             if (count($matchKeyTime) >= 2) {
356:                 $output = $this->getReadableTime((max($matchKeyTime)-min($matchKeyTime))*1000);
357:             } elseif (count($matchKeyMemory) >= 2) {
358:                 $output = $this->getReadableFileSize(max($matchKeyMemory)-min($matchKeyMemory));
359:             }
360: 
361:             unset($matchKeyMemory, $matchKeyTime);
362:         }
363: 
364:         return $output;
365:     }// summaryMatchKey
366: 
367: }
API documentation generated by ApiGen