Completed
Push — master ( c58c9b...07c22d )
by Jacob
02:25
created

PhpQuickProfiler   A

Complexity

Total Complexity 30

Size/Duplication

Total Lines 184
Duplicated Lines 8.15 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 1
Bugs 1 Features 0
Metric Value
wmc 30
lcom 1
cbo 1
dl 15
loc 184
rs 10
c 1
b 1
f 0

11 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
B gatherConsoleData() 0 17 6
B gatherFileData() 0 24 3
A gatherMemoryData() 0 6 1
A gatherQueryData() 0 20 3
A attemptToExplainQuery() 0 12 3
A gatherSpeedData() 0 6 1
A getMicroTime() 0 5 1
B getReadableFileSize() 0 15 6
A getReadableTime() 15 15 4
A display() 0 11 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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
	public $config = '';
24
	
25
	public function __construct($startTime, $config = '/pqp/') {
26
		$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...
27
		$this->config = $config;
28
	}
29
	
30
	/*-------------------------------------------
31
	     FORMAT THE DIFFERENT TYPES OF LOGS
32
	-------------------------------------------*/
33
	
34
	public function gatherConsoleData() {
35
		$logs = Console::getLogs();
36
		if($logs['console']) {
37
			foreach($logs['console'] as $key => $log) {
38
				if($log['type'] == 'log') {
39
					$logs['console'][$key]['data'] = print_r($log['data'], true);
40
				}
41
				elseif($log['type'] == 'memory') {
42
					$logs['console'][$key]['data'] = $this->getReadableFileSize($log['data']);
43
				}
44
				elseif($log['type'] == 'speed') {
45
					$logs['console'][$key]['data'] = $this->getReadableTime(($log['data'] - $this->startTime)*1000);
46
				}
47
			}
48
		}
49
		$this->output['logs'] = $logs;
50
	}
51
	
52
	/*-------------------------------------------
53
	    AGGREGATE DATA ON THE FILES INCLUDED
54
	-------------------------------------------*/
55
	
56
	public function gatherFileData() {
57
		$files = get_included_files();
58
		$fileList = array();
59
		$fileTotals = array(
60
			"count" => count($files),
61
			"size" => 0,
62
			"largest" => 0,
63
		);
64
65
		foreach($files as $key => $file) {
66
			$size = filesize($file);
67
			$fileList[] = array(
68
					'name' => $file,
69
					'size' => $this->getReadableFileSize($size)
70
				);
71
			$fileTotals['size'] += $size;
72
			if($size > $fileTotals['largest']) $fileTotals['largest'] = $size;
73
		}
74
		
75
		$fileTotals['size'] = $this->getReadableFileSize($fileTotals['size']);
76
		$fileTotals['largest'] = $this->getReadableFileSize($fileTotals['largest']);
77
		$this->output['files'] = $fileList;
78
		$this->output['fileTotals'] = $fileTotals;
79
	}
80
	
81
	/*-------------------------------------------
82
	     MEMORY USAGE AND MEMORY AVAILABLE
83
	-------------------------------------------*/
84
	
85
	public function gatherMemoryData() {
86
		$memoryTotals = array();
87
		$memoryTotals['used'] = $this->getReadableFileSize(memory_get_peak_usage());
88
		$memoryTotals['total'] = ini_get("memory_limit");
89
		$this->output['memoryTotals'] = $memoryTotals;
90
	}
91
	
92
	/*--------------------------------------------------------
93
	     QUERY DATA -- DATABASE OBJECT WITH LOGGING REQUIRED
94
	----------------------------------------------------------*/
95
	
96
	public function gatherQueryData() {
97
		$queryTotals = array();
98
		$queryTotals['count'] = 0;
99
		$queryTotals['time'] = 0;
100
		$queries = array();
101
		
102
		if($this->db != '') {
103
			$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...
104
			foreach($this->db->queries as $key => $query) {
105
				$query = $this->attemptToExplainQuery($query);
106
				$queryTotals['time'] += $query['time'];
107
				$query['time'] = $this->getReadableTime($query['time']);
108
				$queries[] = $query;
109
			}
110
		}
111
		
112
		$queryTotals['time'] = $this->getReadableTime($queryTotals['time']);
113
		$this->output['queries'] = $queries;
114
		$this->output['queryTotals'] = $queryTotals;
115
	}
116
	
117
	/*--------------------------------------------------------
118
	     CALL SQL EXPLAIN ON THE QUERY TO FIND MORE INFO
119
	----------------------------------------------------------*/
120
	
121
	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...
122
		try {
123
			$sql = 'EXPLAIN '.$query['sql'];
124
			$rs = $this->db->query($sql);
125
		}
126
		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...
127
		if($rs) {
128
			$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...
129
			$query['explain'] = $row;
130
		}
131
		return $query;
132
	}
133
	
134
	/*-------------------------------------------
135
	     SPEED DATA FOR ENTIRE PAGE LOAD
136
	-------------------------------------------*/
137
	
138
	public function gatherSpeedData() {
139
		$speedTotals = array();
140
		$speedTotals['total'] = $this->getReadableTime(($this->getMicroTime() - $this->startTime)*1000);
141
		$speedTotals['allowed'] = ini_get("max_execution_time");
142
		$this->output['speedTotals'] = $speedTotals;
143
	}
144
	
145
	/*-------------------------------------------
146
	     HELPER FUNCTIONS TO FORMAT DATA
147
	-------------------------------------------*/
148
	
149
	function getMicroTime() {
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...
150
		$time = microtime();
151
		$time = explode(' ', $time);
152
		return $time[1] + $time[0];
153
	}
154
	
155
	public function getReadableFileSize($size, $retstring = null) {
156
        	// adapted from code at http://aidanlister.com/repos/v/function.size_readable.php
157
	       $sizes = array('bytes', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
158
159
	       if ($retstring === null) { $retstring = '%01.2f %s'; }
160
161
		$lastsizestring = end($sizes);
162
163
		foreach ($sizes as $sizestring) {
164
	       	if ($size < 1024) { break; }
165
	           if ($sizestring != $lastsizestring) { $size /= 1024; }
166
	       }
167
	       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 163. 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...
168
	       return sprintf($retstring, $size, $sizestring);
169
	}
170
	
171 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...
172
		$ret = $time;
173
		$formatter = 0;
174
		$formats = array('ms', 's', 'm');
175
		if($time >= 1000 && $time < 60000) {
176
			$formatter = 1;
177
			$ret = ($time / 1000);
178
		}
179
		if($time >= 60000) {
180
			$formatter = 2;
181
			$ret = ($time / 1000) / 60;
182
		}
183
		$ret = number_format($ret,3,'.','') . ' ' . $formats[$formatter];
184
		return $ret;
185
	}
186
	
187
	/*---------------------------------------------------------
188
	     DISPLAY TO THE SCREEN -- CALL WHEN CODE TERMINATING
189
	-----------------------------------------------------------*/
190
	
191
	public function display($db = '', $master_db = '') {
192
		$this->db = $db;
193
		$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...
194
		$this->gatherConsoleData();
195
		$this->gatherFileData();
196
		$this->gatherMemoryData();
197
		$this->gatherQueryData();
198
		$this->gatherSpeedData();
199
		require_once __DIR__ . '/../display.php';
200
		displayPqp($this->output, $this->config);
201
	}
202
	
203
}
204
205
?>
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...
206