Completed
Push — master ( 77243d...dac2cf )
by Jacob
02:14
created

PhpQuickProfiler::getMicroTime()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
dl 0
loc 5
rs 9.4286
c 1
b 1
f 0
cc 1
eloc 4
nc 1
nop 0
1
<?php
2
3
/* - - - - - - - - - - - - - - - - - - - - -
4
5
 Title : PHP Quick Profiler Class
6
 Author : Created by Ryan Campbell
7
 URL : http://particletree.com/features/php-quick-profiler/
8
9
 Last Updated : April 22, 2009
10
11
 Description : This class processes the logs and organizes the data
12
 for output to the browser. Initialize this class with a start time at
13
 the beginning of your code, and then call the display method when your code
14
 is terminating.
15
16
- - - - - - - - - - - - - - - - - - - - - */
17
18
namespace Particletree\Pqp;
19
20
class PhpQuickProfiler {
21
	
22
	public $output = array();
23
24
  protected $console;
25
	
26
	public function __construct($console, $startTime = null) {
27
    $this->console = $console;
28
29
    if (is_null($startTime)) {
30
        $startTime = microtime(true);
31
    }
32
33
		$this->startTime = $startTime;
0 ignored issues
show
Bug introduced by
The property startTime does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
34
	}
35
	
36
	/*-------------------------------------------
37
	     FORMAT THE DIFFERENT TYPES OF LOGS
38
	-------------------------------------------*/
39
	
40
	public function gatherConsoleData() {
41
    $console = array(
42
      'messages' => array(),
43
      'totals' => array(
44
        'log' => 0,
45
        'memory' => 0,
46
        'error' => 0,
47
        'speed' => 0
48
      ));
49
		$logs = $this->console->getLogs();
50
			foreach($logs as $log) {
51
				if($log['type'] == 'log') {
52
					$message = array(
53
            'data' => print_r($log['data'], true),
54
            'type' => 'log'
55
          );
56
          $console['totals']['log']++;
57
				}
58 View Code Duplication
				elseif($log['type'] == 'memory') {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
59
					$message = array(
60
            'name'    => $log['name'],
61
            'data_type'    => $log['data_type'],
62
            'data'   => $this->getReadableFileSize($log['data']),
63
            'type' => 'memory'
64
          );
65
          $console['totals']['memory']++;
66
				}
67 View Code Duplication
				elseif($log['type'] == 'speed') {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
68
          $message = array(
69
            'name' => $log['name'],
70
            'data'    => $this->getReadableTime(($log['data'] - $this->startTime) * 1000),
71
            'type' => 'speed'
72
          );
73
          $console['totals']['speed']++;
74
				} else {
75
          $message = array(
76
            'data' => $log['data'],
77
            'type' => 'error',
78
            'file' => $log['file'],
79
            'line' => $log['line']
80
          );
81
          $console['totals']['error']++;
82
        }
83
        array_push($console['messages'], $message);
84
			}
85
		$this->output['logs'] = array('console' => $console);
86
	}
87
	
88
	/*-------------------------------------------
89
	    AGGREGATE DATA ON THE FILES INCLUDED
90
	-------------------------------------------*/
91
	
92
	public function gatherFileData() {
93
		$files = get_included_files();
94
		$fileList = array();
95
		$fileTotals = array(
96
			"count" => count($files),
97
			"size" => 0,
98
			"largest" => 0,
99
		);
100
101
		foreach($files as $key => $file) {
102
			$size = filesize($file);
103
			$fileList[] = array(
104
					'name' => $file,
105
					'size' => $this->getReadableFileSize($size)
106
				);
107
			$fileTotals['size'] += $size;
108
			if($size > $fileTotals['largest']) $fileTotals['largest'] = $size;
109
		}
110
		
111
		$fileTotals['size'] = $this->getReadableFileSize($fileTotals['size']);
112
		$fileTotals['largest'] = $this->getReadableFileSize($fileTotals['largest']);
113
		$this->output['files'] = $fileList;
114
		$this->output['fileTotals'] = $fileTotals;
115
	}
116
	
117
	/*-------------------------------------------
118
	     MEMORY USAGE AND MEMORY AVAILABLE
119
	-------------------------------------------*/
120
	
121
	public function gatherMemoryData() {
122
		$memoryTotals = array();
123
		$memoryTotals['used'] = $this->getReadableFileSize(memory_get_peak_usage());
124
		$memoryTotals['total'] = ini_get("memory_limit");
125
		$this->output['memoryTotals'] = $memoryTotals;
126
	}
127
	
128
	/*--------------------------------------------------------
129
	     QUERY DATA -- DATABASE OBJECT WITH LOGGING REQUIRED
130
	----------------------------------------------------------*/
131
	
132
	public function gatherQueryData() {
133
		$queryTotals = array();
134
		$queryTotals['count'] = 0;
135
		$queryTotals['time'] = 0;
136
		$queries = array();
137
		
138
		if($this->db != '') {
139
			$queryTotals['count'] += $this->db->queryCount;
0 ignored issues
show
Bug introduced by
The property db does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
140
			foreach($this->db->queries as $key => $query) {
141
				$query = $this->attemptToExplainQuery($query);
142
				$queryTotals['time'] += $query['time'];
143
				$query['time'] = $this->getReadableTime($query['time']);
144
				$queries[] = $query;
145
			}
146
		}
147
		
148
		$queryTotals['time'] = $this->getReadableTime($queryTotals['time']);
149
		$this->output['queries'] = $queries;
150
		$this->output['queryTotals'] = $queryTotals;
151
	}
152
	
153
	/*--------------------------------------------------------
154
	     CALL SQL EXPLAIN ON THE QUERY TO FIND MORE INFO
155
	----------------------------------------------------------*/
156
	
157
	function attemptToExplainQuery($query) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
158
		try {
159
			$sql = 'EXPLAIN '.$query['sql'];
160
			$rs = $this->db->query($sql);
161
		}
162
		catch(Exception $e) {}
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
Bug introduced by
The class Particletree\Pqp\Exception does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
163
		if($rs) {
164
			$row = mysql_fetch_array($rs, MYSQL_ASSOC);
0 ignored issues
show
Bug introduced by
The variable $rs does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
165
			$query['explain'] = $row;
166
		}
167
		return $query;
168
	}
169
	
170
	/*-------------------------------------------
171
	     SPEED DATA FOR ENTIRE PAGE LOAD
172
	-------------------------------------------*/
173
	
174
	public function gatherSpeedData() {
175
		$speedTotals = array();
176
		$speedTotals['total'] = $this->getReadableTime((microtime(true) - $this->startTime)*1000);
177
		$speedTotals['allowed'] = ini_get("max_execution_time");
178
		$this->output['speedTotals'] = $speedTotals;
179
	}
180
	
181
	/*-------------------------------------------
182
	     HELPER FUNCTIONS TO FORMAT DATA
183
	-------------------------------------------*/
184
	
185
	public function getReadableFileSize($size, $retstring = null) {
186
        	// adapted from code at http://aidanlister.com/repos/v/function.size_readable.php
187
	       $sizes = array('bytes', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
188
189
	       if ($retstring === null) { $retstring = '%01.2f %s'; }
190
191
		$lastsizestring = end($sizes);
192
193
		foreach ($sizes as $sizestring) {
194
	       	if ($size < 1024) { break; }
195
	           if ($sizestring != $lastsizestring) { $size /= 1024; }
196
	       }
197
	       if ($sizestring == $sizes[0]) { $retstring = '%01d %s'; } // Bytes aren't normally fractional
0 ignored issues
show
Bug introduced by
The variable $sizestring seems to be defined by a foreach iteration on line 193. Are you sure the iterator is never empty, otherwise this variable is not defined?

It seems like you are relying on a variable being defined by an iteration:

foreach ($a as $b) {
}

// $b is defined here only if $a has elements, for example if $a is array()
// then $b would not be defined here. To avoid that, we recommend to set a
// default value for $b.


// Better
$b = 0; // or whatever default makes sense in your context
foreach ($a as $b) {
}

// $b is now guaranteed to be defined here.
Loading history...
198
	       return sprintf($retstring, $size, $sizestring);
199
	}
200
	
201 View Code Duplication
	public function getReadableTime($time) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
202
		$ret = $time;
203
		$formatter = 0;
204
		$formats = array('ms', 's', 'm');
205
		if($time >= 1000 && $time < 60000) {
206
			$formatter = 1;
207
			$ret = ($time / 1000);
208
		}
209
		if($time >= 60000) {
210
			$formatter = 2;
211
			$ret = ($time / 1000) / 60;
212
		}
213
		$ret = number_format($ret,3,'.','') . ' ' . $formats[$formatter];
214
		return $ret;
215
	}
216
	
217
	/*---------------------------------------------------------
218
	     DISPLAY TO THE SCREEN -- CALL WHEN CODE TERMINATING
219
	-----------------------------------------------------------*/
220
	
221
	public function display($db = '', $master_db = '') {
222
		$this->db = $db;
223
		$this->master_db = $master_db;
0 ignored issues
show
Bug introduced by
The property master_db does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
224
		$this->gatherConsoleData();
225
		$this->gatherFileData();
226
		$this->gatherMemoryData();
227
		$this->gatherQueryData();
228
		$this->gatherSpeedData();
229
		require_once __DIR__ . '/../display.php';
230
		displayPqp($this->output);
231
	}
232
	
233
}
234
235
?>
0 ignored issues
show
Best Practice introduced by
It is not recommended to use PHP's closing tag ?> in files other than templates.

Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore.

A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.

Loading history...
236