This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
0 ignored issues
–
show
|
|||
2 | require_once('FindSSEnvironment.php'); |
||
3 | |||
4 | |||
5 | define('ADMIN_USERNAME', SS_DEFAULT_ADMIN_USERNAME); // Admin Username |
||
6 | define('ADMIN_PASSWORD', SS_DEFAULT_ADMIN_PASSWORD); // Admin Password - CHANGE THIS TO ENABLE!!! |
||
7 | |||
8 | ///////////////// Password protect //////////////////////////////////////////////////////////////// |
||
9 | View Code Duplication | if (!isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW']) || |
|
0 ignored issues
–
show
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. ![]() |
|||
10 | $_SERVER['PHP_AUTH_USER'] != ADMIN_USERNAME ||$_SERVER['PHP_AUTH_PW'] != ADMIN_PASSWORD) { |
||
11 | Header("WWW-Authenticate: Basic realm=\"Memcache Login\""); |
||
12 | Header("HTTP/1.0 401 Unauthorized"); |
||
13 | |||
14 | echo <<<EOB |
||
15 | <html><body> |
||
16 | <h1>Rejected!</h1> |
||
17 | <big>Wrong Username or Password!</big> |
||
18 | </body></html> |
||
19 | EOB; |
||
20 | exit; |
||
21 | } |
||
22 | define('THOUSAND_SEPARATOR', true); |
||
23 | |||
24 | if (!extension_loaded('Zend OPcache')) { |
||
25 | echo '<div style="background-color: #F2DEDE; color: #B94A48; padding: 1em;">You do not have the Zend OPcache extension loaded, sample data is being shown instead.</div>'; |
||
26 | require 'data-sample.php'; |
||
27 | } |
||
28 | |||
29 | class OpCacheDataModel |
||
0 ignored issues
–
show
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.
You can fix this by adding a namespace to your class: namespace YourVendor;
class YourClass { }
When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries. ![]() |
|||
30 | { |
||
31 | private $_configuration; |
||
32 | private $_status; |
||
33 | private $_d3Scripts = array(); |
||
34 | |||
35 | public function __construct() |
||
36 | { |
||
37 | $this->_configuration = opcache_get_configuration(); |
||
38 | $this->_status = opcache_get_status(); |
||
39 | } |
||
40 | |||
41 | public function getPageTitle() |
||
42 | { |
||
43 | return 'PHP ' . phpversion() . " with OpCache {$this->_configuration['version']['version']}"; |
||
44 | } |
||
45 | |||
46 | public function getStatusDataRows() |
||
47 | { |
||
48 | $rows = array(); |
||
49 | foreach ($this->_status as $key => $value) { |
||
50 | if ($key === 'scripts') { |
||
51 | continue; |
||
52 | } |
||
53 | |||
54 | if (is_array($value)) { |
||
55 | foreach ($value as $k => $v) { |
||
0 ignored issues
–
show
The expression
$value of type string|array is not guaranteed to be traversable. How about adding an additional type check?
There are different options of fixing this problem.
![]() |
|||
56 | if ($v === false) { |
||
57 | $value = 'false'; |
||
58 | } |
||
59 | if ($v === true) { |
||
60 | $value = 'true'; |
||
61 | } |
||
62 | if ($k === 'used_memory' || $k === 'free_memory' || $k === 'wasted_memory') { |
||
63 | $v = $this->_size_for_humans( |
||
64 | $v |
||
65 | ); |
||
66 | } |
||
67 | if ($k === 'current_wasted_percentage' || $k === 'opcache_hit_rate') { |
||
68 | $v = number_format( |
||
69 | $v, |
||
70 | 2 |
||
71 | ) . '%'; |
||
72 | } |
||
73 | if ($k === 'blacklist_miss_ratio') { |
||
74 | $v = number_format($v, 2) . '%'; |
||
75 | } |
||
76 | if ($k === 'start_time' || $k === 'last_restart_time') { |
||
77 | $v = ($v ? date(DATE_RFC822, $v) : 'never'); |
||
78 | } |
||
79 | if (THOUSAND_SEPARATOR === true && is_int($v)) { |
||
80 | $v = number_format($v); |
||
81 | } |
||
82 | |||
83 | $rows[] = "<tr><th>$k</th><td>$v</td></tr>\n"; |
||
84 | } |
||
85 | continue; |
||
86 | } |
||
87 | if ($value === false) { |
||
88 | $value = 'false'; |
||
89 | } |
||
90 | if ($value === true) { |
||
91 | $value = 'true'; |
||
92 | } |
||
93 | $rows[] = "<tr><th>$key</th><td>$value</td></tr>\n"; |
||
94 | } |
||
95 | |||
96 | return implode("\n", $rows); |
||
97 | } |
||
98 | |||
99 | public function getConfigDataRows() |
||
100 | { |
||
101 | $rows = array(); |
||
102 | foreach ($this->_configuration['directives'] as $key => $value) { |
||
103 | if ($value === false) { |
||
104 | $value = 'false'; |
||
105 | } |
||
106 | if ($value === true) { |
||
107 | $value = 'true'; |
||
108 | } |
||
109 | if ($key == 'opcache.memory_consumption') { |
||
110 | $value = $this->_size_for_humans($value); |
||
111 | } |
||
112 | $rows[] = "<tr><th>$key</th><td>$value</td></tr>\n"; |
||
113 | } |
||
114 | |||
115 | return implode("\n", $rows); |
||
116 | } |
||
117 | |||
118 | public function getScriptStatusRows() |
||
119 | { |
||
120 | foreach ($this->_status['scripts'] as $key => $data) { |
||
121 | $dirs[dirname($key)][basename($key)] = $data; |
||
0 ignored issues
–
show
Coding Style
Comprehensibility
introduced
by
$dirs was never initialized. Although not strictly required by PHP, it is generally a good practice to add $dirs = array(); before regardless.
Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code. Let’s take a look at an example: foreach ($collection as $item) {
$myArray['foo'] = $item->getFoo();
if ($item->hasBar()) {
$myArray['bar'] = $item->getBar();
}
// do something with $myArray
}
As you can see in this example, the array This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop. ![]() |
|||
122 | $this->_arrayPset($this->_d3Scripts, $key, array( |
||
123 | 'name' => basename($key), |
||
124 | 'size' => $data['memory_consumption'], |
||
125 | )); |
||
126 | } |
||
127 | |||
128 | asort($dirs); |
||
129 | |||
130 | $basename = ''; |
||
131 | while (true) { |
||
132 | if (count($this->_d3Scripts) !=1) { |
||
133 | break; |
||
134 | } |
||
135 | $basename .= DIRECTORY_SEPARATOR . key($this->_d3Scripts); |
||
136 | $this->_d3Scripts = reset($this->_d3Scripts); |
||
137 | } |
||
138 | |||
139 | $this->_d3Scripts = $this->_processPartition($this->_d3Scripts, $basename); |
||
140 | $id = 1; |
||
141 | |||
142 | $rows = array(); |
||
143 | foreach ($dirs as $dir => $files) { |
||
144 | $count = count($files); |
||
145 | $file_plural = $count > 1 ? 's' : null; |
||
146 | $m = 0; |
||
147 | foreach ($files as $file => $data) { |
||
148 | $m += $data["memory_consumption"]; |
||
149 | } |
||
150 | $m = $this->_size_for_humans($m); |
||
151 | |||
152 | if ($count > 1) { |
||
153 | $rows[] = '<tr>'; |
||
154 | $rows[] = "<th class=\"clickable\" id=\"head-{$id}\" colspan=\"3\" onclick=\"toggleVisible('#head-{$id}', '#row-{$id}')\">{$dir} ({$count} file{$file_plural}, {$m})</th>"; |
||
155 | $rows[] = '</tr>'; |
||
156 | } |
||
157 | |||
158 | foreach ($files as $file => $data) { |
||
159 | $rows[] = "<tr id=\"row-{$id}\">"; |
||
160 | $rows[] = "<td>" . $this->_format_value($data["hits"]) . "</td>"; |
||
161 | $rows[] = "<td>" . $this->_size_for_humans($data["memory_consumption"]) . "</td>"; |
||
162 | $rows[] = $count > 1 ? "<td>{$file}</td>" : "<td>{$dir}/{$file}</td>"; |
||
163 | $rows[] = '</tr>'; |
||
164 | } |
||
165 | |||
166 | ++$id; |
||
167 | } |
||
168 | |||
169 | return implode("\n", $rows); |
||
170 | } |
||
171 | |||
172 | public function getScriptStatusCount() |
||
173 | { |
||
174 | return count($this->_status["scripts"]); |
||
175 | } |
||
176 | |||
177 | public function getGraphDataSetJson() |
||
178 | { |
||
179 | $dataset = array(); |
||
180 | $dataset['memory'] = array( |
||
181 | $this->_status['memory_usage']['used_memory'], |
||
182 | $this->_status['memory_usage']['free_memory'], |
||
183 | $this->_status['memory_usage']['wasted_memory'], |
||
184 | ); |
||
185 | |||
186 | $dataset['keys'] = array( |
||
187 | $this->_status['opcache_statistics']['num_cached_keys'], |
||
188 | $this->_status['opcache_statistics']['max_cached_keys'] - $this->_status['opcache_statistics']['num_cached_keys'], |
||
189 | 0 |
||
190 | ); |
||
191 | |||
192 | $dataset['hits'] = array( |
||
193 | $this->_status['opcache_statistics']['misses'], |
||
194 | $this->_status['opcache_statistics']['hits'], |
||
195 | 0, |
||
196 | ); |
||
197 | |||
198 | $dataset['restarts'] = array( |
||
199 | $this->_status['opcache_statistics']['oom_restarts'], |
||
200 | $this->_status['opcache_statistics']['manual_restarts'], |
||
201 | $this->_status['opcache_statistics']['hash_restarts'], |
||
202 | ); |
||
203 | |||
204 | if (THOUSAND_SEPARATOR === true) { |
||
205 | $dataset['TSEP'] = 1; |
||
206 | } else { |
||
207 | $dataset['TSEP'] = 0; |
||
208 | } |
||
209 | |||
210 | return json_encode($dataset); |
||
211 | } |
||
212 | |||
213 | public function getHumanUsedMemory() |
||
214 | { |
||
215 | return $this->_size_for_humans($this->getUsedMemory()); |
||
216 | } |
||
217 | |||
218 | public function getHumanFreeMemory() |
||
219 | { |
||
220 | return $this->_size_for_humans($this->getFreeMemory()); |
||
221 | } |
||
222 | |||
223 | public function getHumanWastedMemory() |
||
224 | { |
||
225 | return $this->_size_for_humans($this->getWastedMemory()); |
||
226 | } |
||
227 | |||
228 | public function getUsedMemory() |
||
0 ignored issues
–
show
The return type could not be reliably inferred; please add a
@return annotation.
Our type inference engine in quite powerful, but sometimes the code does not
provide enough clues to go by. In these cases we request you to add a ![]() |
|||
229 | { |
||
230 | return $this->_status['memory_usage']['used_memory']; |
||
231 | } |
||
232 | |||
233 | public function getFreeMemory() |
||
0 ignored issues
–
show
The return type could not be reliably inferred; please add a
@return annotation.
Our type inference engine in quite powerful, but sometimes the code does not
provide enough clues to go by. In these cases we request you to add a ![]() |
|||
234 | { |
||
235 | return $this->_status['memory_usage']['free_memory']; |
||
236 | } |
||
237 | |||
238 | public function getWastedMemory() |
||
0 ignored issues
–
show
The return type could not be reliably inferred; please add a
@return annotation.
Our type inference engine in quite powerful, but sometimes the code does not
provide enough clues to go by. In these cases we request you to add a ![]() |
|||
239 | { |
||
240 | return $this->_status['memory_usage']['wasted_memory']; |
||
241 | } |
||
242 | |||
243 | public function getWastedMemoryPercentage() |
||
244 | { |
||
245 | return number_format($this->_status['memory_usage']['current_wasted_percentage'], 2); |
||
246 | } |
||
247 | |||
248 | public function getD3Scripts() |
||
249 | { |
||
250 | return $this->_d3Scripts; |
||
251 | } |
||
252 | |||
253 | private function _processPartition($value, $name = null) |
||
0 ignored issues
–
show
The return type could not be reliably inferred; please add a
@return annotation.
Our type inference engine in quite powerful, but sometimes the code does not
provide enough clues to go by. In these cases we request you to add a ![]() |
|||
254 | { |
||
255 | if (array_key_exists('size', $value)) { |
||
256 | return $value; |
||
257 | } |
||
258 | |||
259 | $array = array('name' => $name,'children' => array()); |
||
260 | |||
261 | foreach ($value as $k => $v) { |
||
262 | $array['children'][] = $this->_processPartition($v, $k); |
||
263 | } |
||
264 | |||
265 | return $array; |
||
266 | } |
||
267 | |||
268 | private function _format_value($value) |
||
0 ignored issues
–
show
The return type could not be reliably inferred; please add a
@return annotation.
Our type inference engine in quite powerful, but sometimes the code does not
provide enough clues to go by. In these cases we request you to add a ![]() |
|||
269 | { |
||
270 | if (THOUSAND_SEPARATOR === true) { |
||
271 | return number_format($value); |
||
272 | } else { |
||
273 | return $value; |
||
274 | } |
||
275 | } |
||
276 | |||
277 | private function _size_for_humans($bytes) |
||
278 | { |
||
279 | if ($bytes > 1048576) { |
||
280 | return sprintf('%.2f MB', $bytes / 1048576); |
||
281 | } else { |
||
282 | if ($bytes > 1024) { |
||
283 | return sprintf('%.2f kB', $bytes / 1024); |
||
284 | } else { |
||
285 | return sprintf('%d bytes', $bytes); |
||
286 | } |
||
287 | } |
||
288 | } |
||
289 | |||
290 | // Borrowed from Laravel |
||
291 | private function _arrayPset(&$array, $key, $value) |
||
0 ignored issues
–
show
The return type could not be reliably inferred; please add a
@return annotation.
Our type inference engine in quite powerful, but sometimes the code does not
provide enough clues to go by. In these cases we request you to add a ![]() |
|||
292 | { |
||
293 | if (is_null($key)) { |
||
294 | return $array = $value; |
||
295 | } |
||
296 | $keys = explode(DIRECTORY_SEPARATOR, ltrim($key, DIRECTORY_SEPARATOR)); |
||
297 | while (count($keys) > 1) { |
||
298 | $key = array_shift($keys); |
||
299 | if (! isset($array[$key]) || ! is_array($array[$key])) { |
||
300 | $array[$key] = array(); |
||
301 | } |
||
302 | $array =& $array[$key]; |
||
303 | } |
||
304 | $array[array_shift($keys)] = $value; |
||
305 | return $array; |
||
306 | } |
||
307 | } |
||
308 | |||
309 | $dataModel = new OpCacheDataModel(); |
||
310 | ?> |
||
311 | <!DOCTYPE html> |
||
312 | <meta charset="utf-8"> |
||
313 | <html> |
||
314 | <head> |
||
315 | <style> |
||
316 | body { |
||
317 | font-family: "Helvetica Neue",Helvetica,Arial,sans-serif; |
||
318 | margin: 0; |
||
319 | padding: 0; |
||
320 | } |
||
321 | |||
322 | #container { |
||
323 | width: 1024px; |
||
324 | margin: auto; |
||
325 | position: relative; |
||
326 | } |
||
327 | |||
328 | h1 { |
||
329 | padding: 10px 0; |
||
330 | } |
||
331 | |||
332 | table { |
||
333 | border-collapse: collapse; |
||
334 | } |
||
335 | |||
336 | tbody tr:nth-child(even) { |
||
337 | background-color: #eee; |
||
338 | } |
||
339 | |||
340 | p.capitalize { |
||
341 | text-transform: capitalize; |
||
342 | } |
||
343 | |||
344 | .tabs { |
||
345 | position: relative; |
||
346 | float: left; |
||
347 | width: 60%; |
||
348 | } |
||
349 | |||
350 | .tab { |
||
351 | float: left; |
||
352 | } |
||
353 | |||
354 | .tab label { |
||
355 | background: #eee; |
||
356 | padding: 10px 12px; |
||
357 | border: 1px solid #ccc; |
||
358 | margin-left: -1px; |
||
359 | position: relative; |
||
360 | left: 1px; |
||
361 | } |
||
362 | |||
363 | .tab [type=radio] { |
||
364 | display: none; |
||
365 | } |
||
366 | |||
367 | .tab th, .tab td { |
||
368 | padding: 8px 12px; |
||
369 | } |
||
370 | |||
371 | .content { |
||
372 | position: absolute; |
||
373 | top: 28px; |
||
374 | left: 0; |
||
375 | background: white; |
||
376 | border: 1px solid #ccc; |
||
377 | height: 450px; |
||
378 | width: 100%; |
||
379 | overflow: auto; |
||
380 | } |
||
381 | |||
382 | .content table { |
||
383 | width: 100%; |
||
384 | } |
||
385 | |||
386 | .content th, .tab:nth-child(3) td { |
||
387 | text-align: left; |
||
388 | } |
||
389 | |||
390 | .content td { |
||
391 | text-align: right; |
||
392 | } |
||
393 | |||
394 | .clickable { |
||
395 | cursor: pointer; |
||
396 | } |
||
397 | |||
398 | [type=radio]:checked ~ label { |
||
399 | background: white; |
||
400 | border-bottom: 1px solid white; |
||
401 | z-index: 2; |
||
402 | } |
||
403 | |||
404 | [type=radio]:checked ~ label ~ .content { |
||
405 | z-index: 1; |
||
406 | } |
||
407 | |||
408 | #graph { |
||
409 | float: right; |
||
410 | width: 40%; |
||
411 | position: relative; |
||
412 | } |
||
413 | |||
414 | #graph > form { |
||
415 | position: absolute; |
||
416 | right: 60px; |
||
417 | top: -20px; |
||
418 | } |
||
419 | |||
420 | #graph > svg { |
||
421 | position: absolute; |
||
422 | top: 0; |
||
423 | right: 0; |
||
424 | } |
||
425 | |||
426 | #stats { |
||
427 | position: absolute; |
||
428 | right: 125px; |
||
429 | top: 145px; |
||
430 | } |
||
431 | |||
432 | #stats th, #stats td { |
||
433 | padding: 6px 10px; |
||
434 | font-size: 0.8em; |
||
435 | } |
||
436 | |||
437 | #partition { |
||
438 | position: absolute; |
||
439 | width: 100%; |
||
440 | height: 100%; |
||
441 | z-index: 10; |
||
442 | top: 0; |
||
443 | left: 0; |
||
444 | background: #ddd; |
||
445 | display: none; |
||
446 | } |
||
447 | |||
448 | #close-partition { |
||
449 | display: none; |
||
450 | position: absolute; |
||
451 | z-index: 20; |
||
452 | right: 15px; |
||
453 | top: 15px; |
||
454 | background: #f9373d; |
||
455 | color: #fff; |
||
456 | padding: 12px 15px; |
||
457 | } |
||
458 | |||
459 | #close-partition:hover { |
||
460 | background: #D32F33; |
||
461 | cursor: pointer; |
||
462 | } |
||
463 | |||
464 | #partition rect { |
||
465 | stroke: #fff; |
||
466 | fill: #aaa; |
||
467 | fill-opacity: 1; |
||
468 | } |
||
469 | |||
470 | #partition rect.parent { |
||
471 | cursor: pointer; |
||
472 | fill: steelblue; |
||
473 | } |
||
474 | |||
475 | #partition text { |
||
476 | pointer-events: none; |
||
477 | } |
||
478 | |||
479 | label { |
||
480 | cursor: pointer; |
||
481 | } |
||
482 | </style> |
||
483 | <script src="//cdnjs.cloudflare.com/ajax/libs/d3/3.0.1/d3.v3.min.js"></script> |
||
484 | <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> |
||
485 | <script> |
||
486 | var hidden = {}; |
||
487 | function toggleVisible(head, row) { |
||
488 | if (!hidden[row]) { |
||
489 | d3.selectAll(row).transition().style('display', 'none'); |
||
490 | hidden[row] = true; |
||
491 | d3.select(head).transition().style('color', '#ccc'); |
||
492 | } else { |
||
493 | d3.selectAll(row).transition().style('display'); |
||
494 | hidden[row] = false; |
||
495 | d3.select(head).transition().style('color', '#000'); |
||
496 | } |
||
497 | } |
||
498 | </script> |
||
499 | <title><?php echo $dataModel->getPageTitle(); ?></title> |
||
500 | </head> |
||
501 | |||
502 | <body> |
||
503 | <div id="container"> |
||
504 | <h1><?php echo $dataModel->getPageTitle(); ?></h1> |
||
505 | |||
506 | <div class="tabs"> |
||
507 | |||
508 | <div class="tab"> |
||
509 | <input type="radio" id="tab-status" name="tab-group-1" checked> |
||
510 | <label for="tab-status">Status</label> |
||
511 | <div class="content"> |
||
512 | <table> |
||
513 | <?php echo $dataModel->getStatusDataRows(); ?> |
||
514 | </table> |
||
515 | </div> |
||
516 | </div> |
||
517 | |||
518 | <div class="tab"> |
||
519 | <input type="radio" id="tab-config" name="tab-group-1"> |
||
520 | <label for="tab-config">Configuration</label> |
||
521 | <div class="content"> |
||
522 | <table> |
||
523 | <?php echo $dataModel->getConfigDataRows(); ?> |
||
524 | </table> |
||
525 | </div> |
||
526 | </div> |
||
527 | |||
528 | <div class="tab"> |
||
529 | <input type="radio" id="tab-scripts" name="tab-group-1"> |
||
530 | <label for="tab-scripts">Scripts (<?php echo $dataModel->getScriptStatusCount(); ?>)</label> |
||
531 | <div class="content"> |
||
532 | <table style="font-size:0.8em;"> |
||
533 | <tr> |
||
534 | <th width="10%">Hits</th> |
||
535 | <th width="20%">Memory</th> |
||
536 | <th width="70%">Path</th> |
||
537 | </tr> |
||
538 | <?php echo $dataModel->getScriptStatusRows(); ?> |
||
539 | </table> |
||
540 | </div> |
||
541 | </div> |
||
542 | |||
543 | <div class="tab"> |
||
544 | <input type="radio" id="tab-visualise" name="tab-group-1"> |
||
545 | <label for="tab-visualise">Visualise Partition</label> |
||
546 | <div class="content"></div> |
||
547 | </div> |
||
548 | |||
549 | </div> |
||
550 | |||
551 | <div id="graph"> |
||
552 | <form> |
||
553 | <label><input type="radio" name="dataset" value="memory" checked> Memory</label> |
||
554 | <label><input type="radio" name="dataset" value="keys"> Keys</label> |
||
555 | <label><input type="radio" name="dataset" value="hits"> Hits</label> |
||
556 | <label><input type="radio" name="dataset" value="restarts"> Restarts</label> |
||
557 | </form> |
||
558 | |||
559 | <div id="stats"></div> |
||
560 | </div> |
||
561 | </div> |
||
562 | |||
563 | <div id="close-partition">✖ Close Visualisation</div> |
||
564 | <div id="partition"></div> |
||
565 | |||
566 | <script> |
||
567 | var dataset = <?php echo $dataModel->getGraphDataSetJson(); ?>; |
||
568 | |||
569 | var width = 400, |
||
570 | height = 400, |
||
571 | radius = Math.min(width, height) / 2, |
||
572 | colours = ['#B41F1F', '#1FB437', '#ff7f0e']; |
||
573 | |||
574 | d3.scale.customColours = function() { |
||
575 | return d3.scale.ordinal().range(colours); |
||
576 | }; |
||
577 | |||
578 | var colour = d3.scale.customColours(); |
||
579 | var pie = d3.layout.pie().sort(null); |
||
580 | |||
581 | var arc = d3.svg.arc().innerRadius(radius - 20).outerRadius(radius - 50); |
||
582 | var svg = d3.select("#graph").append("svg") |
||
583 | .attr("width", width) |
||
584 | .attr("height", height) |
||
585 | .append("g") |
||
586 | .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")"); |
||
587 | |||
588 | var path = svg.selectAll("path") |
||
589 | .data(pie(dataset.memory)) |
||
590 | .enter().append("path") |
||
591 | .attr("fill", function(d, i) { return colour(i); }) |
||
592 | .attr("d", arc) |
||
593 | .each(function(d) { this._current = d; }); // store the initial values |
||
594 | |||
595 | d3.selectAll("input").on("change", change); |
||
596 | set_text("memory"); |
||
597 | |||
598 | function set_text(t) { |
||
599 | if (t === "memory") { |
||
600 | d3.select("#stats").html( |
||
601 | "<table><tr><th style='background:#B41F1F;'>Used</th><td><?php echo $dataModel->getHumanUsedMemory()?></td></tr>"+ |
||
602 | "<tr><th style='background:#1FB437;'>Free</th><td><?php echo $dataModel->getHumanFreeMemory()?></td></tr>"+ |
||
603 | "<tr><th style='background:#ff7f0e;' rowspan=\"2\">Wasted</th><td><?php echo $dataModel->getHumanWastedMemory()?></td></tr>"+ |
||
604 | "<tr><td><?php echo $dataModel->getWastedMemoryPercentage()?>%</td></tr></table>" |
||
605 | ); |
||
606 | } else if (t === "keys") { |
||
607 | d3.select("#stats").html( |
||
608 | "<table><tr><th style='background:#B41F1F;'>Cached keys</th><td>"+format_value(dataset[t][0])+"</td></tr>"+ |
||
609 | "<tr><th style='background:#1FB437;'>Free Keys</th><td>"+format_value(dataset[t][1])+"</td></tr></table>" |
||
610 | ); |
||
611 | } else if (t === "hits") { |
||
612 | d3.select("#stats").html( |
||
613 | "<table><tr><th style='background:#B41F1F;'>Misses</th><td>"+format_value(dataset[t][0])+"</td></tr>"+ |
||
614 | "<tr><th style='background:#1FB437;'>Cache Hits</th><td>"+format_value(dataset[t][1])+"</td></tr></table>" |
||
615 | ); |
||
616 | } else if (t === "restarts") { |
||
617 | d3.select("#stats").html( |
||
618 | "<table><tr><th style='background:#B41F1F;'>Memory</th><td>"+dataset[t][0]+"</td></tr>"+ |
||
619 | "<tr><th style='background:#1FB437;'>Manual</th><td>"+dataset[t][1]+"</td></tr>"+ |
||
620 | "<tr><th style='background:#ff7f0e;'>Keys</th><td>"+dataset[t][2]+"</td></tr></table>" |
||
621 | ); |
||
622 | } |
||
623 | } |
||
624 | |||
625 | function change() { |
||
626 | // Filter out any zero values to see if there is anything left |
||
627 | var remove_zero_values = dataset[this.value].filter(function(value) { |
||
628 | return value > 0; |
||
629 | }); |
||
630 | |||
631 | // Skip if the value is undefined for some reason |
||
632 | if (typeof dataset[this.value] !== 'undefined' && remove_zero_values.length > 0) { |
||
633 | $('#graph').find('> svg').show(); |
||
634 | path = path.data(pie(dataset[this.value])); // update the data |
||
635 | path.transition().duration(750).attrTween("d", arcTween); // redraw the arcs |
||
636 | // Hide the graph if we can't draw it correctly, not ideal but this works |
||
637 | } else { |
||
638 | $('#graph').find('> svg').hide(); |
||
639 | } |
||
640 | |||
641 | set_text(this.value); |
||
642 | } |
||
643 | |||
644 | function arcTween(a) { |
||
645 | var i = d3.interpolate(this._current, a); |
||
646 | this._current = i(0); |
||
647 | return function(t) { |
||
648 | return arc(i(t)); |
||
649 | }; |
||
650 | } |
||
651 | |||
652 | function size_for_humans(bytes) { |
||
653 | if (bytes > 1048576) { |
||
654 | return (bytes/1048576).toFixed(2) + ' MB'; |
||
655 | } else if (bytes > 1024) { |
||
656 | return (bytes/1024).toFixed(2) + ' KB'; |
||
657 | } else return bytes + ' bytes'; |
||
658 | } |
||
659 | |||
660 | function format_value(value) { |
||
661 | if (dataset["TSEP"] == 1) { |
||
662 | return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); |
||
663 | } else { |
||
664 | return value; |
||
665 | } |
||
666 | } |
||
667 | |||
668 | var w = window.innerWidth, |
||
669 | h = window.innerHeight, |
||
670 | x = d3.scale.linear().range([0, w]), |
||
671 | y = d3.scale.linear().range([0, h]); |
||
672 | |||
673 | var vis = d3.select("#partition") |
||
674 | .style("width", w + "px") |
||
675 | .style("height", h + "px") |
||
676 | .append("svg:svg") |
||
677 | .attr("width", w) |
||
678 | .attr("height", h); |
||
679 | |||
680 | var partition = d3.layout.partition() |
||
681 | .value(function(d) { return d.size; }); |
||
682 | |||
683 | root = JSON.parse('<?php echo json_encode($dataModel->getD3Scripts()); ?>'); |
||
684 | |||
685 | var g = vis.selectAll("g") |
||
686 | .data(partition.nodes(root)) |
||
687 | .enter().append("svg:g") |
||
688 | .attr("transform", function(d) { return "translate(" + x(d.y) + "," + y(d.x) + ")"; }) |
||
689 | .on("click", click); |
||
690 | |||
691 | var kx = w / root.dx, |
||
692 | ky = h / 1; |
||
693 | |||
694 | g.append("svg:rect") |
||
695 | .attr("width", root.dy * kx) |
||
696 | .attr("height", function(d) { return d.dx * ky; }) |
||
697 | .attr("class", function(d) { return d.children ? "parent" : "child"; }); |
||
698 | |||
699 | g.append("svg:text") |
||
700 | .attr("transform", transform) |
||
701 | .attr("dy", ".35em") |
||
702 | .style("opacity", function(d) { return d.dx * ky > 12 ? 1 : 0; }) |
||
703 | .text(function(d) { return d.name; }) |
||
704 | |||
705 | d3.select(window) |
||
706 | .on("click", function() { click(root); }) |
||
707 | |||
708 | function click(d) { |
||
709 | if (!d.children) return; |
||
710 | |||
711 | kx = (d.y ? w - 40 : w) / (1 - d.y); |
||
712 | ky = h / d.dx; |
||
713 | x.domain([d.y, 1]).range([d.y ? 40 : 0, w]); |
||
714 | y.domain([d.x, d.x + d.dx]); |
||
715 | |||
716 | var t = g.transition() |
||
717 | .duration(d3.event.altKey ? 7500 : 750) |
||
718 | .attr("transform", function(d) { return "translate(" + x(d.y) + "," + y(d.x) + ")"; }); |
||
719 | |||
720 | t.select("rect") |
||
721 | .attr("width", d.dy * kx) |
||
722 | .attr("height", function(d) { return d.dx * ky; }); |
||
723 | |||
724 | t.select("text") |
||
725 | .attr("transform", transform) |
||
726 | .style("opacity", function(d) { return d.dx * ky > 12 ? 1 : 0; }); |
||
727 | |||
728 | d3.event.stopPropagation(); |
||
729 | } |
||
730 | |||
731 | function transform(d) { |
||
732 | return "translate(8," + d.dx * ky / 2 + ")"; |
||
733 | } |
||
734 | |||
735 | $(document).ready(function() { |
||
736 | |||
737 | function handleVisualisationToggle(close) { |
||
738 | |||
739 | $('#partition, #close-partition').fadeToggle(); |
||
740 | |||
741 | // Is the visualisation being closed? If so show the status tab again |
||
742 | if (close) { |
||
743 | |||
744 | $('#tab-visualise').removeAttr('checked'); |
||
745 | $('#tab-status').trigger('click'); |
||
746 | |||
747 | } |
||
748 | |||
749 | } |
||
750 | |||
751 | $('label[for="tab-visualise"], #close-partition').on('click', function() { |
||
752 | |||
753 | handleVisualisationToggle(($(this).attr('id') === 'close-partition')); |
||
754 | |||
755 | }); |
||
756 | |||
757 | $(document).keyup(function(e) { |
||
758 | |||
759 | if (e.keyCode == 27) handleVisualisationToggle(true); |
||
760 | |||
761 | }); |
||
762 | |||
763 | }); |
||
764 | </script> |
||
765 | </body> |
||
766 | </html> |
||
767 |
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.