|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
/***************************************** |
|
4
|
|
|
* Title : PHP Quick Profiler Class |
|
5
|
|
|
* Author : Created by Ryan Campbell |
|
6
|
|
|
* URL : http://particletree.com/features/php-quick-profiler/ |
|
7
|
|
|
* Description : This class processes the logs and organizes the data |
|
8
|
|
|
* for output to the browser. Initialize this class with a start time |
|
9
|
|
|
* at the beginning of your code, and then call the display method when |
|
10
|
|
|
* your code is terminating. |
|
11
|
|
|
*****************************************/ |
|
12
|
|
|
|
|
13
|
|
|
namespace Particletree\Pqp; |
|
14
|
|
|
|
|
15
|
|
|
class PhpQuickProfiler |
|
16
|
|
|
{ |
|
17
|
|
|
|
|
18
|
|
|
/** @var Console */ |
|
19
|
|
|
protected $console; |
|
20
|
|
|
|
|
21
|
|
|
/** @var integer */ |
|
22
|
|
|
protected $startTime; |
|
23
|
|
|
|
|
24
|
|
|
/** @var object */ |
|
25
|
|
|
protected $pdo; |
|
26
|
|
|
|
|
27
|
|
|
/** |
|
28
|
|
|
* @param Console $console |
|
29
|
|
|
* @param object $pdo |
|
30
|
|
|
* @param integer $startTime |
|
31
|
|
|
*/ |
|
32
|
|
|
public function __construct(Console $console, $pdo = null, $startTime = null) |
|
33
|
|
|
{ |
|
34
|
|
|
$this->console = $console; |
|
35
|
|
|
$this->pdo = $pdo; |
|
36
|
|
|
|
|
37
|
|
|
if (is_null($startTime)) { |
|
38
|
|
|
$startTime = microtime(true); |
|
39
|
|
|
} |
|
40
|
|
|
$this->startTime = $startTime; |
|
|
|
|
|
|
41
|
|
|
} |
|
42
|
|
|
|
|
43
|
|
|
/** |
|
44
|
|
|
* Get data about files loaded for the application to current point |
|
45
|
|
|
* |
|
46
|
|
|
* @returns array |
|
47
|
|
|
*/ |
|
48
|
|
|
public function gatherFileData() |
|
49
|
|
|
{ |
|
50
|
|
|
$files = get_included_files(); |
|
51
|
|
|
$data = array(); |
|
52
|
|
|
foreach ($files as $file) { |
|
53
|
|
|
array_push($data, array( |
|
54
|
|
|
'name' => $file, |
|
55
|
|
|
'size' => filesize($file) |
|
56
|
|
|
)); |
|
57
|
|
|
} |
|
58
|
|
|
return $data; |
|
59
|
|
|
} |
|
60
|
|
|
|
|
61
|
|
|
/** |
|
62
|
|
|
* Get data about memory usage of the application |
|
63
|
|
|
* |
|
64
|
|
|
* @returns array |
|
65
|
|
|
*/ |
|
66
|
|
|
public function gatherMemoryData() |
|
67
|
|
|
{ |
|
68
|
|
|
$usedMemory = memory_get_peak_usage(); |
|
69
|
|
|
$allowedMemory = ini_get('memory_limit'); |
|
70
|
|
|
return array( |
|
71
|
|
|
'used' => $usedMemory, |
|
72
|
|
|
'allowed' => $allowedMemory |
|
73
|
|
|
); |
|
74
|
|
|
} |
|
75
|
|
|
|
|
76
|
|
|
/** |
|
77
|
|
|
* Get data about sql usage of the application |
|
78
|
|
|
* |
|
79
|
|
|
* @param array $profiledQueries |
|
80
|
|
|
* @returns array |
|
81
|
|
|
*/ |
|
82
|
|
|
public function gatherQueryData(array $profiledQueries) |
|
83
|
|
|
{ |
|
84
|
|
|
$data = array(); |
|
85
|
|
|
foreach ($profiledQueries as $query) { |
|
86
|
|
|
if ($query['function'] !== 'perform') { |
|
87
|
|
|
continue; |
|
88
|
|
|
} |
|
89
|
|
|
|
|
90
|
|
|
array_push($data, array( |
|
91
|
|
|
'sql' => $query['statement'], |
|
92
|
|
|
'explain' => $this->explainQuery($query['statement'], $query['bind_values']), |
|
93
|
|
|
'time' => $query['duration'] |
|
94
|
|
|
)); |
|
95
|
|
|
} |
|
96
|
|
|
return $data; |
|
97
|
|
|
} |
|
98
|
|
|
|
|
99
|
|
|
/** |
|
100
|
|
|
* Attempts to explain a query |
|
101
|
|
|
* |
|
102
|
|
|
* @param string $query |
|
103
|
|
|
* @param array $parameters |
|
104
|
|
|
* @return array |
|
105
|
|
|
*/ |
|
106
|
|
|
protected function explainQuery($query, $parameters) |
|
107
|
|
|
{ |
|
108
|
|
|
$query = "EXPLAIN {$query}"; |
|
109
|
|
|
try { |
|
110
|
|
|
$statement = $this->pdo->prepare($query); |
|
111
|
|
|
$statement->execute($parameters); |
|
112
|
|
|
return $statement->fetch(\PDO::FETCH_ASSOC); |
|
113
|
|
|
} catch (\Exception $e) { |
|
114
|
|
|
echo $e->getMessage(); |
|
115
|
|
|
} |
|
116
|
|
|
return ''; |
|
|
|
|
|
|
117
|
|
|
} |
|
118
|
|
|
|
|
119
|
|
|
/** |
|
120
|
|
|
* Get data about speed of the application |
|
121
|
|
|
* |
|
122
|
|
|
* @returns array |
|
123
|
|
|
*/ |
|
124
|
|
|
public function gatherSpeedData() |
|
125
|
|
|
{ |
|
126
|
|
|
$elapsedTime = microtime(true) - $this->startTime; |
|
127
|
|
|
$allowedTime = ini_get('max_execution_time'); |
|
128
|
|
|
return array( |
|
129
|
|
|
'elapsed' => $elapsedTime, |
|
130
|
|
|
'allowed' => $allowedTime |
|
131
|
|
|
); |
|
132
|
|
|
} |
|
133
|
|
|
|
|
134
|
|
|
/** |
|
135
|
|
|
* Triggers end display of the profiling data |
|
136
|
|
|
* |
|
137
|
|
|
* @param Display $display |
|
138
|
|
|
* @param array $profiledQueries |
|
139
|
|
|
*/ |
|
140
|
|
|
public function display(Display $display, array $profiledQueries = array()) |
|
141
|
|
|
{ |
|
142
|
|
|
$display->setConsole($this->console); |
|
143
|
|
|
$display->setFileData($this->gatherFileData()); |
|
144
|
|
|
$display->setMemoryData($this->gatherMemoryData()); |
|
145
|
|
|
$display->setQueryData($this->gatherQueryData($profiledQueries)); |
|
146
|
|
|
$display->setSpeedData($this->gatherSpeedData()); |
|
147
|
|
|
|
|
148
|
|
|
$display(); |
|
149
|
|
|
} |
|
150
|
|
|
} |
|
151
|
|
|
|
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.
For example, imagine you have a variable
$accountIdthat can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theidproperty of an instance of theAccountclass. This class holds a proper account, so the id value must no longer be false.Either this assignment is in error or a type check should be added for that assignment.