memcache.php ➔ getCacheItems()   B
last analyzed

Complexity

Conditions 6
Paths 3

Size

Total Lines 25
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 16
nc 3
nop 0
dl 0
loc 25
rs 8.439
c 0
b 0
f 0
1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 26 and the first side effect is on line 3.

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.

Loading history...
2
3
require_once('FindSSEnvironment.php');
4
5
/*
6
  +----------------------------------------------------------------------+
7
  | PHP Version 5                                                        |
8
  +----------------------------------------------------------------------+
9
  | Copyright (c) 1997-2014 The PHP Group                                |
10
  +----------------------------------------------------------------------+
11
  | This source file is subject to version 3.0 of the PHP license,       |
12
  | that is bundled with this package in the file LICENSE, and is        |
13
  | available through the world-wide-web at the following url:           |
14
  | http://www.php.net/license/3_0.txt.                                  |
15
  | If you did not receive a copy of the PHP license and are unable to   |
16
  | obtain it through the world-wide-web, please send a note to          |
17
  | [email protected] so we can mail you a copy immediately.               |
18
  +----------------------------------------------------------------------+
19
  | Author:  Harun Yayli <harunyayli at gmail.com>                       |
20
  | Modifications by: kn007 http://kn007.net                             |
21
  +----------------------------------------------------------------------+
22
*/
23
24
$VERSION='$Id: memcache.php,v 1.1.2.3 2008/08/28 18:07:54 mikl Exp $';
25
26
define('ADMIN_USERNAME', SS_DEFAULT_ADMIN_USERNAME);            // Admin Username
27
define('ADMIN_PASSWORD', SS_DEFAULT_ADMIN_PASSWORD);    // Admin Password - CHANGE THIS TO ENABLE!!!
28
define('DATE_FORMAT', 'Y/m/d H:i:s');
29
define('GRAPH_SIZE', 200);
30
define('MAX_ITEM_DUMP', 50);
31
32
$MEMCACHE_SERVERS[] = '127.0.0.1:'.MEM_CACHE_PORT; // add more as an array
33
//$MEMCACHE_SERVERS[] = '/tmp/memcached.sock:0'; // add more as an array
34
35
36
////////// END OF DEFAULT CONFIG AREA /////////////////////////////////////////////////////////////
37
38
///////////////// Password protect ////////////////////////////////////////////////////////////////
39 View Code Duplication
if (!isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW']) ||
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...
40
           $_SERVER['PHP_AUTH_USER'] != ADMIN_USERNAME ||$_SERVER['PHP_AUTH_PW'] != ADMIN_PASSWORD) {
41
    Header("WWW-Authenticate: Basic realm=\"Memcache Login\"");
42
    Header("HTTP/1.0 401 Unauthorized");
43
44
    echo <<<EOB
45
                <html><body>
46
                <h1>Rejected!</h1>
47
                <big>Wrong Username or Password!</big>
48
                </body></html>
49
EOB;
50
    exit;
51
}
52
///////////MEMCACHE FUNCTIONS /////////////////////////////////////////////////////////////////////
53
54
function sendMemcacheCommands($command)
55
{
56
    global $MEMCACHE_SERVERS;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
57
    $result = array();
58
59
    foreach ($MEMCACHE_SERVERS as $server) {
60
        $strs = explode(':', $server);
61
        $host = $strs[0];
62
        $port = $strs[1];
63
        $result[$server] = sendMemcacheCommand($host, $port, $command);
64
    }
65
    return $result;
66
}
67
function sendMemcacheCommand($server, $port, $command)
0 ignored issues
show
Documentation introduced by
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 @return annotation as described here.

Loading history...
68
{
69
    if ($port == 0) {
70
        $s = @stream_socket_client('unix://'.$server);
71
    } else {
72
        $s = @fsockopen($server, $port);
73
    }
74
    if (!$s) {
75
        die("Cant connect to:".$server.':'.$port);
0 ignored issues
show
Coding Style Compatibility introduced by
The function sendMemcacheCommand() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
76
    }
77
78
    fwrite($s, $command."\r\n");
79
80
    $buf='';
81
    while ((!feof($s))) {
82
        $buf .= fgets($s, 256);
83
        if (strpos($buf, "END\r\n")!==false) { // stat says end
84
            break;
85
        }
86
        if (strpos($buf, "DELETED\r\n")!==false || strpos($buf, "NOT_FOUND\r\n")!==false) { // delete says these
87
            break;
88
        }
89
        if (strpos($buf, "OK\r\n")!==false) { // flush_all says ok
90
            break;
91
        }
92
    }
93
    fclose($s);
94
    return parseMemcacheResults($buf);
95
}
96
function parseMemcacheResults($str)
0 ignored issues
show
Documentation introduced by
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 @return annotation as described here.

Loading history...
97
{
98
    $res = array();
99
    $lines = explode("\r\n", $str);
100
    $cnt = count($lines);
101
    for ($i=0; $i< $cnt; $i++) {
102
        $line = $lines[$i];
103
        $l = explode(' ', $line, 3);
104
        if (count($l)==3) {
105
            $res[$l[0]][$l[1]]=$l[2];
106
            if ($l[0]=='VALUE') { // next line is the value
107
                $res[$l[0]][$l[1]] = array();
108
                list($flag, $size)=explode(' ', $l[2]);
109
                $res[$l[0]][$l[1]]['stat']=array('flag'=>$flag,'size'=>$size);
110
                $res[$l[0]][$l[1]]['value']=$lines[++$i];
111
            }
112
        } elseif ($line=='DELETED' || $line=='NOT_FOUND' || $line=='OK') {
113
            return $line;
114
        }
115
    }
116
    return $res;
117
}
118
119
function dumpCacheSlab($server, $slabId, $limit)
0 ignored issues
show
Documentation introduced by
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 @return annotation as described here.

Loading history...
120
{
121
    list($host, $port) = explode(':', $server);
122
    $resp = sendMemcacheCommand($host, $port, 'stats cachedump '.$slabId.' '.$limit);
123
124
    return $resp;
125
}
126
127
function flushServer($server)
0 ignored issues
show
Documentation introduced by
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 @return annotation as described here.

Loading history...
128
{
129
    list($host, $port) = explode(':', $server);
130
    $resp = sendMemcacheCommand($host, $port, 'flush_all');
131
    return $resp;
132
}
133
function getCacheItems()
134
{
135
    $items = sendMemcacheCommands('stats items');
136
    $serverItems = array();
137
    $totalItems = array();
138
    foreach ($items as $server=>$itemlist) {
139
        $serverItems[$server] = array();
140
        $totalItems[$server]=0;
141
        if (!isset($itemlist['STAT'])) {
142
            continue;
143
        }
144
145
        $iteminfo = $itemlist['STAT'];
146
147
        foreach ($iteminfo as $keyinfo=>$value) {
148
            if (preg_match('/items\:(\d+?)\:(.+?)$/', $keyinfo, $matches)) {
149
                $serverItems[$server][$matches[1]][$matches[2]] = $value;
150
                if ($matches[2]=='number') {
151
                    $totalItems[$server] +=$value;
152
                }
153
            }
154
        }
155
    }
156
    return array('items'=>$serverItems,'counts'=>$totalItems);
157
}
158
function getMemcacheStats($total=true)
159
{
160
    $resp = sendMemcacheCommands('stats');
161
    if ($total) {
162
        $res = array();
163
        foreach ($resp as $server=>$r) {
164
            foreach ($r['STAT'] as $key=>$row) {
165
                if (!isset($res[$key])) {
166
                    $res[$key]=null;
167
                }
168
                switch ($key) {
169
                    case 'pid':
170
                        $res['pid'][$server]=$row;
171
                        break;
172
                    case 'uptime':
173
                        $res['uptime'][$server]=$row;
174
                        break;
175
                    case 'time':
176
                        $res['time'][$server]=$row;
177
                        break;
178
                    case 'version':
179
                        $res['version'][$server]=$row;
180
                        break;
181
                    case 'pointer_size':
182
                        $res['pointer_size'][$server]=$row;
183
                        break;
184
                    case 'rusage_user':
185
                        $res['rusage_user'][$server]=$row;
186
                        break;
187
                    case 'rusage_system':
188
                        $res['rusage_system'][$server]=$row;
189
                        break;
190
                    case 'curr_items':
191
                        $res['curr_items']+=$row;
192
                        break;
193
                    case 'total_items':
194
                        $res['total_items']+=$row;
195
                        break;
196
                    case 'bytes':
197
                        $res['bytes']+=$row;
198
                        break;
199
                    case 'curr_connections':
200
                        $res['curr_connections']+=$row;
201
                        break;
202
                    case 'total_connections':
203
                        $res['total_connections']+=$row;
204
                        break;
205
                    case 'connection_structures':
206
                        $res['connection_structures']+=$row;
207
                        break;
208
                    case 'cmd_get':
209
                        $res['cmd_get']+=$row;
210
                        break;
211
                    case 'cmd_set':
212
                        $res['cmd_set']+=$row;
213
                        break;
214
                    case 'get_hits':
215
                        $res['get_hits']+=$row;
216
                        break;
217
                    case 'get_misses':
218
                        $res['get_misses']+=$row;
219
                        break;
220
                    case 'evictions':
221
                        $res['evictions']+=$row;
222
                        break;
223
                    case 'bytes_read':
224
                        $res['bytes_read']+=$row;
225
                        break;
226
                    case 'bytes_written':
227
                        $res['bytes_written']+=$row;
228
                        break;
229
                    case 'limit_maxbytes':
230
                        $res['limit_maxbytes']+=$row;
231
                        break;
232
                    case 'threads':
233
                        $res['rusage_system'][$server]=$row;
234
                        break;
235
                }
236
            }
237
        }
238
        return $res;
239
    }
240
    return $resp;
241
}
242
243
//////////////////////////////////////////////////////
244
245
//
246
// don't cache this page
247
//
248
header("Cache-Control: no-store, no-cache, must-revalidate");  // HTTP/1.1
249
header("Cache-Control: post-check=0, pre-check=0", false);
250
header("Pragma: no-cache");                                    // HTTP/1.0
251
252 View Code Duplication
function duration($ts)
0 ignored issues
show
Best Practice introduced by
The function duration() has been defined more than once; this definition is ignored, only the first definition in code/tests/apc.php (L280-320) is considered.

This check looks for functions that have already been defined in other files.

Some Codebases, like WordPress, make a practice of defining functions multiple times. This may lead to problems with the detection of function parameters and types. If you really need to do this, you can mark the duplicate definition with the @ignore annotation.

/**
 * @ignore
 */
function getUser() {

}

function getUser($id, $realm) {

}

See also the PhpDoc documentation for @ignore.

Loading history...
Duplication introduced by
This function 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...
253
{
254
    global $time;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
255
    $years = (int)((($time - $ts)/(7*86400))/52.177457);
256
    $rem = (int)(($time-$ts)-($years * 52.177457 * 7 * 86400));
257
    $weeks = (int)(($rem)/(7*86400));
258
    $days = (int)(($rem)/86400) - $weeks*7;
259
    $hours = (int)(($rem)/3600) - $days*24 - $weeks*7*24;
260
    $mins = (int)(($rem)/60) - $hours*60 - $days*24*60 - $weeks*7*24*60;
261
    $str = '';
262
    if ($years==1) {
263
        $str .= "$years year, ";
264
    }
265
    if ($years>1) {
266
        $str .= "$years years, ";
267
    }
268
    if ($weeks==1) {
269
        $str .= "$weeks week, ";
270
    }
271
    if ($weeks>1) {
272
        $str .= "$weeks weeks, ";
273
    }
274
    if ($days==1) {
275
        $str .= "$days day,";
276
    }
277
    if ($days>1) {
278
        $str .= "$days days,";
279
    }
280
    if ($hours == 1) {
281
        $str .= " $hours hour and";
282
    }
283
    if ($hours>1) {
284
        $str .= " $hours hours and";
285
    }
286
    if ($mins == 1) {
287
        $str .= " 1 minute";
288
    } else {
289
        $str .= " $mins minutes";
290
    }
291
    return $str;
292
}
293
294
// create graphics
295
//
296
function graphics_avail()
0 ignored issues
show
Best Practice introduced by
The function graphics_avail() has been defined more than once; this definition is ignored, only the first definition in code/tests/apc.php (L324-327) is considered.

This check looks for functions that have already been defined in other files.

Some Codebases, like WordPress, make a practice of defining functions multiple times. This may lead to problems with the detection of function parameters and types. If you really need to do this, you can mark the duplicate definition with the @ignore annotation.

/**
 * @ignore
 */
function getUser() {

}

function getUser($id, $realm) {

}

See also the PhpDoc documentation for @ignore.

Loading history...
297
{
298
    return extension_loaded('gd');
299
}
300
301 View Code Duplication
function bsize($s)
0 ignored issues
show
Best Practice introduced by
The function bsize() has been defined more than once; this definition is ignored, only the first definition in code/tests/apc.php (L557-566) is considered.

This check looks for functions that have already been defined in other files.

Some Codebases, like WordPress, make a practice of defining functions multiple times. This may lead to problems with the detection of function parameters and types. If you really need to do this, you can mark the duplicate definition with the @ignore annotation.

/**
 * @ignore
 */
function getUser() {

}

function getUser($id, $realm) {

}

See also the PhpDoc documentation for @ignore.

Loading history...
Duplication introduced by
This function 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...
302
{
303
    foreach (array('', 'K', 'M', 'G') as $i => $k) {
304
        if ($s < 1024) {
305
            break;
306
        }
307
        $s/=1024;
308
    }
309
    return sprintf("%5.1f %sBytes", $s, $k);
0 ignored issues
show
Bug introduced by
The variable $k seems to be defined by a foreach iteration on line 303. 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...
310
}
311
312
// create menu entry
313
function menu_entry($ob, $title)
0 ignored issues
show
Best Practice introduced by
The function menu_entry() has been defined more than once; this definition is ignored, only the first definition in code/tests/apc.php (L580-590) is considered.

This check looks for functions that have already been defined in other files.

Some Codebases, like WordPress, make a practice of defining functions multiple times. This may lead to problems with the detection of function parameters and types. If you really need to do this, you can mark the duplicate definition with the @ignore annotation.

/**
 * @ignore
 */
function getUser() {

}

function getUser($id, $realm) {

}

See also the PhpDoc documentation for @ignore.

Loading history...
Documentation introduced by
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 @return annotation as described here.

Loading history...
Coding Style introduced by
menu_entry uses the super-global variable $_GET which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
314
{
315
    global $PHP_SELF;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
316
    if ($ob==$_GET['op']) {
317
        return "<li><a class=\"child_active\" href=\"$PHP_SELF&op=$ob\">$title</a></li>";
318
    }
319
    return "<li><a class=\"active\" href=\"$PHP_SELF&op=$ob\">$title</a></li>";
320
}
321
322
function getHeader()
323
{
324
    $header = <<<EOB
325
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
326
<html>
327
<head><title>MEMCACHE INFO</title>
328
<style type="text/css"><!--
329
body { background:white; font-size:100.01%; margin:0; padding:0; }
330
body,p,td,th,input,submit { font-size:0.8em;font-family:arial,helvetica,sans-serif; }
331
* html body   {font-size:0.8em}
332
* html p      {font-size:0.8em}
333
* html td     {font-size:0.8em}
334
* html th     {font-size:0.8em}
335
* html input  {font-size:0.8em}
336
* html submit {font-size:0.8em}
337
td { vertical-align:top }
338
a { color:black; font-weight:none; text-decoration:none; }
339
a:hover { text-decoration:underline; }
340
div.content { padding:1em 1em 1em 1em; position:absolute; width:97%; z-index:100; }
341
342
h1.memcache { background:rgb(153,153,204); margin:0; padding:0.5em 1em 0.5em 1em; }
343
* html h1.memcache { margin-bottom:-7px; }
344
h1.memcache a:hover { text-decoration:none; color:rgb(90,90,90); }
345
h1.memcache span.logo {
346
    background:rgb(119,123,180);
347
    color:black;
348
    border-right: solid black 1px;
349
    border-bottom: solid black 1px;
350
    font-style:italic;
351
    font-size:1em;
352
    padding-left:1.2em;
353
    padding-right:1.2em;
354
    text-align:right;
355
    display:block;
356
    width:130px;
357
    }
358
h1.memcache span.logo span.name { color:white; font-size:0.7em; padding:0 0.8em 0 2em; }
359
h1.memcache span.nameinfo { color:white; display:inline; font-size:0.4em; margin-left: 3em; }
360
h1.memcache div.copy { color:black; font-size:0.4em; position:absolute; right:1em; }
361
hr.memcache {
362
    background:white;
363
    border-bottom:solid rgb(102,102,153) 1px;
364
    border-style:none;
365
    border-top:solid rgb(102,102,153) 10px;
366
    height:12px;
367
    margin:0;
368
    margin-top:1px;
369
    padding:0;
370
}
371
372
ol,menu { margin:1em 0 0 0; padding:0.2em; margin-left:1em;}
373
ol.menu li { display:inline; margin-right:0.7em; list-style:none; font-size:85%}
374
ol.menu a {
375
    background:rgb(153,153,204);
376
    border:solid rgb(102,102,153) 2px;
377
    color:white;
378
    font-weight:bold;
379
    margin-right:0em;
380
    padding:0.1em 0.5em 0.1em 0.5em;
381
    text-decoration:none;
382
    margin-left: 5px;
383
    }
384
ol.menu a.child_active {
385
    background:rgb(153,153,204);
386
    border:solid rgb(102,102,153) 2px;
387
    color:white;
388
    font-weight:bold;
389
    margin-right:0em;
390
    padding:0.1em 0.5em 0.1em 0.5em;
391
    text-decoration:none;
392
    border-left: solid black 5px;
393
    margin-left: 0px;
394
    }
395
ol.menu span.active {
396
    background:rgb(153,153,204);
397
    border:solid rgb(102,102,153) 2px;
398
    color:black;
399
    font-weight:bold;
400
    margin-right:0em;
401
    padding:0.1em 0.5em 0.1em 0.5em;
402
    text-decoration:none;
403
    border-left: solid black 5px;
404
    }
405
ol.menu span.inactive {
406
    background:rgb(193,193,244);
407
    border:solid rgb(182,182,233) 2px;
408
    color:white;
409
    font-weight:bold;
410
    margin-right:0em;
411
    padding:0.1em 0.5em 0.1em 0.5em;
412
    text-decoration:none;
413
    margin-left: 5px;
414
    }
415
ol.menu a:hover {
416
    background:rgb(193,193,244);
417
    text-decoration:none;
418
    }
419
420
421
div.info {
422
    background:rgb(204,204,204);
423
    border:solid rgb(204,204,204) 1px;
424
    margin-bottom:1em;
425
    }
426
div.info h2 {
427
    background:rgb(204,204,204);
428
    color:black;
429
    font-size:1em;
430
    margin:0;
431
    padding:0.1em 1em 0.1em 1em;
432
    }
433
div.info table {
434
    border:solid rgb(204,204,204) 1px;
435
    border-spacing:0;
436
    width:100%;
437
    }
438
div.info table th {
439
    background:rgb(204,204,204);
440
    color:white;
441
    margin:0;
442
    padding:0.1em 1em 0.1em 1em;
443
    }
444
div.info table th a.sortable { color:black; }
445
div.info table tr.tr-0 { background:rgb(238,238,238); }
446
div.info table tr.tr-1 { background:rgb(221,221,221); }
447
div.info table td { padding:0.3em 1em 0.3em 1em; }
448
div.info table td.td-0 { border-right:solid rgb(102,102,153) 1px; white-space:nowrap; }
449
div.info table td.td-n { border-right:solid rgb(102,102,153) 1px; }
450
div.info table td h3 {
451
    color:black;
452
    font-size:1.1em;
453
    margin-left:-0.3em;
454
    }
455
.td-0 a , .td-n a, .tr-0 a , tr-1 a {
456
    text-decoration:underline;
457
}
458
div.graph { margin-bottom:1em }
459
div.graph h2 { background:rgb(204,204,204);; color:black; font-size:1em; margin:0; padding:0.1em 1em 0.1em 1em; }
460
div.graph table { border:solid rgb(204,204,204) 1px; color:black; font-weight:normal; width:100%; }
461
div.graph table td.td-0 { background:rgb(238,238,238); }
462
div.graph table td.td-1 { background:rgb(221,221,221); }
463
div.graph table td { padding:0.2em 1em 0.4em 1em; }
464
465
div.div1,div.div2 { margin-bottom:1em; width:35em; }
466
div.div3 { position:absolute; left:40em; top:1em; width:580px; }
467
//div.div3 { position:absolute; left:37em; top:1em; right:1em; }
468
469
div.sorting { margin:1.5em 0em 1.5em 2em }
470
.center { text-align:center }
471
.aright { position:absolute;right:1em }
472
.right { text-align:right }
473
.ok { color:rgb(0,200,0); font-weight:bold}
474
.failed { color:rgb(200,0,0); font-weight:bold}
475
476
span.box {
477
    border: black solid 1px;
478
    border-right:solid black 2px;
479
    border-bottom:solid black 2px;
480
    padding:0 0.5em 0 0.5em;
481
    margin-right:1em;
482
}
483
span.green { background:#60F060; padding:0 0.5em 0 0.5em}
484
span.red { background:#D06030; padding:0 0.5em 0 0.5em }
485
486
div.authneeded {
487
    background:rgb(238,238,238);
488
    border:solid rgb(204,204,204) 1px;
489
    color:rgb(200,0,0);
490
    font-size:1.2em;
491
    font-weight:bold;
492
    padding:2em;
493
    text-align:center;
494
    }
495
496
input {
497
    background:rgb(153,153,204);
498
    border:solid rgb(102,102,153) 2px;
499
    color:white;
500
    font-weight:bold;
501
    margin-right:1em;
502
    padding:0.1em 0.5em 0.1em 0.5em;
503
    }
504
//-->
505
</style>
506
</head>
507
<body>
508
<div class="head">
509
    <h1 class="memcache">
510
        <span class="logo"><a href="http://pecl.php.net/package/memcache">memcache</a></span>
511
        <span class="nameinfo">memcache.php by <a href="http://livebookmark.net">Harun Yayli</a></span>
512
    </h1>
513
    <hr class="memcache">
514
</div>
515
<div class=content>
516
EOB;
517
518
    return $header;
519
}
520
function getFooter()
521
{
522
    global $VERSION;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
523
    $footer = '</div><!-- Based on apc.php '.$VERSION.'--></body>
524
</html>
525
';
526
527
    return $footer;
528
}
529
function getMenu()
0 ignored issues
show
Coding Style introduced by
getMenu uses the super-global variable $_GET which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
530
{
531
    global $PHP_SELF;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
532
    echo "<ol class=menu>";
533
    if ($_GET['op']!=4) {
534
        echo <<<EOB
535
    <li><a href="$PHP_SELF&op={$_GET['op']}">Refresh Data</a></li>
536
EOB;
537
    } else {
538
        echo <<<EOB
539
    <li><a href="$PHP_SELF&op=2}">Back</a></li>
540
EOB;
541
    }
542
    echo
543
    menu_entry(1, 'View Host Stats'),
544
    menu_entry(2, 'Variables');
545
546
    echo <<<EOB
547
    </ol>
548
    <br/>
549
EOB;
550
}
551
552
// TODO, AUTH
553
554
$_GET['op'] = !isset($_GET['op'])? '1':$_GET['op'];
555
$PHP_SELF= isset($_SERVER['PHP_SELF']) ? htmlentities(strip_tags($_SERVER['PHP_SELF'], '')) : '';
556
557
$PHP_SELF=$PHP_SELF.'?';
558
$time = time();
559
// sanitize _GET
560
561
foreach ($_GET as $key=>$g) {
562
    $_GET[$key]=htmlentities($g);
563
}
564
565
566
// singleout
567
// when singleout is set, it only gives details for that server.
568
if (isset($_GET['singleout']) && $_GET['singleout']>=0 && $_GET['singleout'] <count($MEMCACHE_SERVERS)) {
569
    $MEMCACHE_SERVERS = array($MEMCACHE_SERVERS[$_GET['singleout']]);
570
}
571
572
// display images
573
if (isset($_GET['IMG'])) {
574
    $memcacheStats = getMemcacheStats();
575
    $memcacheStatsSingle = getMemcacheStats(false);
576
577
    if (!graphics_avail()) {
578
        exit(0);
579
    }
580
581 View Code Duplication
    function fill_box($im, $x, $y, $w, $h, $color1, $color2, $text='', $placeindex='')
0 ignored issues
show
Best Practice introduced by
The function fill_box() has been defined more than once; this definition is ignored, only the first definition in code/tests/apc.php (L375-412) is considered.

This check looks for functions that have already been defined in other files.

Some Codebases, like WordPress, make a practice of defining functions multiple times. This may lead to problems with the detection of function parameters and types. If you really need to do this, you can mark the duplicate definition with the @ignore annotation.

/**
 * @ignore
 */
function getUser() {

}

function getUser($id, $realm) {

}

See also the PhpDoc documentation for @ignore.

Loading history...
Duplication introduced by
This function 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...
582
    {
583
        global $col_black;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
584
        $x1=$x+$w-1;
585
        $y1=$y+$h-1;
586
587
        imagerectangle($im, $x, $y1, $x1+1, $y+1, $col_black);
588
        if ($y1>$y) {
589
            imagefilledrectangle($im, $x, $y, $x1, $y1, $color2);
590
        } else {
591
            imagefilledrectangle($im, $x, $y1, $x1, $y, $color2);
592
        }
593
        imagerectangle($im, $x, $y1, $x1, $y, $color1);
594
        if ($text) {
595
            if ($placeindex>0) {
596
                if ($placeindex<16) {
597
                    $px=5;
598
                    $py=$placeindex*12+6;
599
                    imagefilledrectangle($im, $px+90, $py+3, $px+90-4, $py-3, $color2);
600
                    imageline($im, $x, $y+$h/2, $px+90, $py, $color2);
601
                    imagestring($im, 2, $px, $py-6, $text, $color1);
602
                } else {
603
                    if ($placeindex<31) {
604
                        $px=$x+40*2;
605
                        $py=($placeindex-15)*12+6;
606
                    } else {
607
                        $px=$x+40*2+100*intval(($placeindex-15)/15);
608
                        $py=($placeindex%15)*12+6;
609
                    }
610
                    imagefilledrectangle($im, $px, $py+3, $px-4, $py-3, $color2);
611
                    imageline($im, $x+$w, $y+$h/2, $px, $py, $color2);
612
                    imagestring($im, 2, $px+2, $py-6, $text, $color1);
613
                }
614
            } else {
615
                imagestring($im, 4, $x+5, $y1-16, $text, $color1);
616
            }
617
        }
618
    }
619
620
621 View Code Duplication
    function fill_arc($im, $centerX, $centerY, $diameter, $start, $end, $color1, $color2, $text='', $placeindex=0)
0 ignored issues
show
Best Practice introduced by
The function fill_arc() has been defined more than once; this definition is ignored, only the first definition in code/tests/apc.php (L333-360) is considered.

This check looks for functions that have already been defined in other files.

Some Codebases, like WordPress, make a practice of defining functions multiple times. This may lead to problems with the detection of function parameters and types. If you really need to do this, you can mark the duplicate definition with the @ignore annotation.

/**
 * @ignore
 */
function getUser() {

}

function getUser($id, $realm) {

}

See also the PhpDoc documentation for @ignore.

Loading history...
Duplication introduced by
This function 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...
622
    {
623
        $r=$diameter/2;
624
        $w=deg2rad((360+$start+($end-$start)/2)%360);
625
626
627
        if (function_exists("imagefilledarc")) {
628
            // exists only if GD 2.0.1 is avaliable
629
            imagefilledarc($im, $centerX+1, $centerY+1, $diameter, $diameter, $start, $end, $color1, IMG_ARC_PIE);
630
            imagefilledarc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color2, IMG_ARC_PIE);
631
            imagefilledarc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color1, IMG_ARC_NOFILL|IMG_ARC_EDGED);
632
        } else {
633
            imagearc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color2);
634
            imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($start)) * $r, $centerY + sin(deg2rad($start)) * $r, $color2);
635
            imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($start+1)) * $r, $centerY + sin(deg2rad($start)) * $r, $color2);
636
            imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($end-1))   * $r, $centerY + sin(deg2rad($end))   * $r, $color2);
637
            imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($end))   * $r, $centerY + sin(deg2rad($end))   * $r, $color2);
638
            imagefill($im, $centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2, $color2);
639
        }
640
        if ($text) {
641
            if ($placeindex>0) {
642
                imageline($im, $centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2, $diameter, $placeindex*12, $color1);
643
                imagestring($im, 4, $diameter, $placeindex*12, $text, $color1);
644
            } else {
645
                imagestring($im, 4, $centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2, $text, $color1);
646
            }
647
        }
648
    }
649
    $size = GRAPH_SIZE; // image size
650
    $image = imagecreate($size+50, $size+10);
651
652
    $col_white = imagecolorallocate($image, 0xFF, 0xFF, 0xFF);
653
    $col_red   = imagecolorallocate($image, 0xD0, 0x60, 0x30);
654
    $col_green = imagecolorallocate($image, 0x60, 0xF0, 0x60);
655
    $col_black = imagecolorallocate($image, 0, 0, 0);
656
657
    imagecolortransparent($image, $col_white);
658
659
    switch ($_GET['IMG']) {
660
        case 1: // pie chart
661
            $tsize=$memcacheStats['limit_maxbytes'];
662
            $avail=$tsize-$memcacheStats['bytes'];
663
            $x=$y=$size/2;
664
            $angle_from = 0;
665
            $fuzz = 0.000001;
666
667
            foreach ($memcacheStatsSingle as $serv=>$mcs) {
668
                $free = $mcs['STAT']['limit_maxbytes']-$mcs['STAT']['bytes'];
669
                $used = $mcs['STAT']['bytes'];
670
671
672 View Code Duplication
                if ($free>0) {
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...
673
                    // draw free
674
                    $angle_to = ($free*360)/$tsize;
675
                    $perc =sprintf("%.2f%%", ($free *100) / $tsize) ;
676
677
                    fill_arc($image, $x, $y, $size, $angle_from, $angle_from + $angle_to, $col_black, $col_green, $perc);
678
                    $angle_from = $angle_from + $angle_to ;
679
                }
680 View Code Duplication
                if ($used>0) {
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...
681
                    // draw used
682
                    $angle_to = ($used*360)/$tsize;
683
                    $perc =sprintf("%.2f%%", ($used *100) / $tsize) ;
684
                    fill_arc($image, $x, $y, $size, $angle_from, $angle_from + $angle_to, $col_black, $col_red, '('.$perc.')');
685
                    $angle_from = $angle_from+ $angle_to ;
686
                }
687
            }
688
689
        break;
690
691
        case 2: // hit miss
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
692
693
            $hits = ($memcacheStats['get_hits']==0) ? 1:$memcacheStats['get_hits'];
694
            $misses = ($memcacheStats['get_misses']==0) ? 1:$memcacheStats['get_misses'];
695
            $total = $hits + $misses ;
696
697
               fill_box($image, 30, $size, 50, -$hits*($size-21)/$total, $col_black, $col_green, sprintf("%.1f%%", $hits*100/$total));
698
            fill_box($image, 130, $size, 50, -max(4, ($total-$hits)*($size-21)/$total), $col_black, $col_red, sprintf("%.1f%%", $misses*100/$total));
699
        break;
700
701
    }
702
    header("Content-type: image/png");
703
    imagepng($image);
704
    exit;
705
}
706
707
echo getHeader();
708
echo getMenu();
709
710
switch ($_GET['op']) {
711
712
    case 1: // host stats
713
        $phpversion = phpversion();
714
        $memcacheStats = getMemcacheStats();
715
        $memcacheStatsSingle = getMemcacheStats(false);
716
717
        $mem_size = $memcacheStats['limit_maxbytes'];
718
        $mem_used = $memcacheStats['bytes'];
719
        $mem_avail= $mem_size-$mem_used;
720
        $startTime = time()-array_sum($memcacheStats['uptime']);
721
722
        $curr_items = $memcacheStats['curr_items'];
723
        $total_items = $memcacheStats['total_items'];
724
        $hits = ($memcacheStats['get_hits']==0) ? 1:$memcacheStats['get_hits'];
725
        $misses = ($memcacheStats['get_misses']==0) ? 1:$memcacheStats['get_misses'];
726
        $sets = $memcacheStats['cmd_set'];
727
728
           $req_rate = sprintf("%.2f", ($hits+$misses)/($time-$startTime));
729
        $hit_rate = sprintf("%.2f", ($hits)/($time-$startTime));
730
        $miss_rate = sprintf("%.2f", ($misses)/($time-$startTime));
731
        $set_rate = sprintf("%.2f", ($sets)/($time-$startTime));
732
733
        echo <<< EOB
734
        <div class="info div1"><h2>General Cache Information</h2>
735
        <table cellspacing=0><tbody>
736
        <tr class=tr-1><td class=td-0>PHP Version</td><td>$phpversion</td></tr>
737
EOB;
738
        echo "<tr class=tr-0><td class=td-0>Memcached Host". ((count($MEMCACHE_SERVERS)>1) ? 's':'')."</td><td>";
739
        $i=0;
740
        if (!isset($_GET['singleout']) && count($MEMCACHE_SERVERS)>1) {
741
            foreach ($MEMCACHE_SERVERS as $server) {
742
                echo($i+1).'. <a href="'.$PHP_SELF.'&singleout='.$i++.'">'.$server.'</a><br/>';
743
            }
744
        } else {
745
            echo '1.'.$MEMCACHE_SERVERS[0];
746
        }
747
        if (isset($_GET['singleout'])) {
748
            echo '<a href="'.$PHP_SELF.'">(all servers)</a><br/>';
749
        }
750
        echo "</td></tr>\n";
751
        echo "<tr class=tr-1><td class=td-0>Total Memcache Cache</td><td>".bsize($memcacheStats['limit_maxbytes'])."</td></tr>\n";
752
753
    echo <<<EOB
754
        </tbody></table>
755
        </div>
756
757
        <div class="info div1"><h2>Memcache Server Information</h2>
758
EOB;
759
        foreach ($MEMCACHE_SERVERS as $server) {
760
            echo '<table cellspacing=0><tbody>';
761
            echo '<tr class=tr-1><td class=td-1>'.$server.'</td><td><a href="'.$PHP_SELF.'&server='.array_search($server, $MEMCACHE_SERVERS).'&op=6">[<b>Flush this server</b>]</a></td></tr>';
762
            echo '<tr class=tr-0><td class=td-0>Start Time</td><td>',date(DATE_FORMAT, $memcacheStatsSingle[$server]['STAT']['time']-$memcacheStatsSingle[$server]['STAT']['uptime']),'</td></tr>';
763
            echo '<tr class=tr-1><td class=td-0>Uptime</td><td>',duration($memcacheStatsSingle[$server]['STAT']['time']-$memcacheStatsSingle[$server]['STAT']['uptime']),'</td></tr>';
764
            echo '<tr class=tr-0><td class=td-0>Memcached Server Version</td><td>'.$memcacheStatsSingle[$server]['STAT']['version'].'</td></tr>';
765
            echo '<tr class=tr-1><td class=td-0>Used Cache Size</td><td>',bsize($memcacheStatsSingle[$server]['STAT']['bytes']),'</td></tr>';
766
            echo '<tr class=tr-0><td class=td-0>Total Cache Size</td><td>',bsize($memcacheStatsSingle[$server]['STAT']['limit_maxbytes']),'</td></tr>';
767
            echo '</tbody></table>';
768
        }
769
    echo <<<EOB
770
771
        </div>
772
        <div class="graph div3"><h2>Host Status Diagrams</h2>
773
        <table cellspacing=0><tbody>
774
EOB;
775
776
    $size='width='.(GRAPH_SIZE+50).' height='.(GRAPH_SIZE+10);
777
    echo <<<EOB
778
        <tr>
779
        <td class=td-0>Cache Usage</td>
780
        <td class=td-1>Hits &amp; Misses</td>
781
        </tr>
782
EOB;
783
784
    echo
785
        graphics_avail() ?
786
              '<tr>'.
787
              "<td class=td-0><img alt=\"\" $size src=\"$PHP_SELF&IMG=1&".(isset($_GET['singleout'])? 'singleout='.$_GET['singleout'].'&':'')."$time\"></td>".
788
              "<td class=td-1><img alt=\"\" $size src=\"$PHP_SELF&IMG=2&".(isset($_GET['singleout'])? 'singleout='.$_GET['singleout'].'&':'')."$time\"></td></tr>\n"
789
            : "",
790
        '<tr>',
791
        '<td class=td-0><span class="green box">&nbsp;</span>Free: ',bsize($mem_avail).sprintf(" (%.1f%%)", $mem_avail*100/$mem_size),"</td>\n",
792
        '<td class=td-1><span class="green box">&nbsp;</span>Hits: ',$hits.sprintf(" (%.1f%%)", $hits*100/($hits+$misses)),"</td>\n",
793
        '</tr>',
794
        '<tr>',
795
        '<td class=td-0><span class="red box">&nbsp;</span>Used: ',bsize($mem_used).sprintf(" (%.1f%%)", $mem_used *100/$mem_size),"</td>\n",
796
        '<td class=td-1><span class="red box">&nbsp;</span>Misses: ',$misses.sprintf(" (%.1f%%)", $misses*100/($hits+$misses)),"</td>\n";
797
        echo <<< EOB
798
    </tr>
799
    </tbody></table>
800
<br/>
801
    <div class="info"><h2>Cache Information</h2>
802
        <table cellspacing=0><tbody>
803
        <tr class=tr-0><td class=td-0>Current Items(total)</td><td>$curr_items ($total_items)</td></tr>
804
        <tr class=tr-1><td class=td-0>Hits</td><td>{$hits}</td></tr>
805
        <tr class=tr-0><td class=td-0>Misses</td><td>{$misses}</td></tr>
806
        <tr class=tr-1><td class=td-0>Request Rate (hits, misses)</td><td>$req_rate cache requests/second</td></tr>
807
        <tr class=tr-0><td class=td-0>Hit Rate</td><td>$hit_rate cache requests/second</td></tr>
808
        <tr class=tr-1><td class=td-0>Miss Rate</td><td>$miss_rate cache requests/second</td></tr>
809
        <tr class=tr-0><td class=td-0>Set Rate</td><td>$set_rate cache requests/second</td></tr>
810
        </tbody></table>
811
        </div>
812
813
EOB;
814
815
    break;
816
817
    case 2: // variables
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
818
819
        $m=0;
820
        $cacheItems= getCacheItems();
821
        $items = $cacheItems['items'];
822
        $totals = $cacheItems['counts'];
823
        $maxDump = MAX_ITEM_DUMP;
824
        foreach ($items as $server => $entries) {
825
            echo <<< EOB
826
827
            <div class="info"><table cellspacing=0><tbody>
828
            <tr><th colspan="2">$server</th></tr>
829
            <tr><th>Slab Id</th><th>Info</th></tr>
830
EOB;
831
832
            foreach ($entries as $slabId => $slab) {
833
                $dumpUrl = $PHP_SELF.'&op=2&server='.(array_search($server, $MEMCACHE_SERVERS)).'&dumpslab='.$slabId;
834
                echo
835
                    "<tr class=tr-$m>",
836
                    "<td class=td-0><center>",'<a href="',$dumpUrl,'">',$slabId,'</a>',"</center></td>",
837
                    "<td class=td-last><b>Item count:</b> ",$slab['number'],'<br/><b>Age:</b>',duration($time-$slab['age']),'<br/> <b>Evicted:</b>',((isset($slab['evicted']) && $slab['evicted']==1)? 'Yes':'No');
838
                if ((isset($_GET['dumpslab']) && $_GET['dumpslab']==$slabId) &&  (isset($_GET['server']) && $_GET['server']==array_search($server, $MEMCACHE_SERVERS))) {
839
                    echo "<br/><b>Items: item</b><br/>";
840
                    $items = dumpCacheSlab($server, $slabId, $slab['number']);
841
                    // maybe someone likes to do a pagination here :)
842
                    $i=1;
843
                    foreach ($items['ITEM'] as $itemKey=>$itemInfo) {
844
                        $itemInfo = trim($itemInfo, '[ ]');
845
846
847
                        echo '<a href="',$PHP_SELF,'&op=4&server=',(array_search($server, $MEMCACHE_SERVERS)),'&key=',base64_encode($itemKey).'">',$itemKey,'</a>';
848
                        if ($i++ % 10 == 0) {
849
                            echo '<br/>';
850
                        } elseif ($i!=$slab['number']+1) {
851
                            echo ',';
852
                        }
853
                    }
854
                }
855
856
                echo "</td></tr>";
857
                $m=1-$m;
858
            }
859
            echo <<<EOB
860
            </tbody></table>
861
            </div><hr/>
862
EOB;
863
        }
864
        break;
865
866
    break;
867
868
    case 4: //item dump
869
        if (!isset($_GET['key']) || !isset($_GET['server'])) {
870
            echo "No key set!";
871
            break;
872
        }
873
        // I'm not doing anything to check the validity of the key string.
874
        // probably an exploit can be written to delete all the files in key=base64_encode("\n\r delete all").
875
        // somebody has to do a fix to this.
876
        $theKey = htmlentities(base64_decode($_GET['key']));
877
878
        $theserver = $MEMCACHE_SERVERS[(int)$_GET['server']];
879
        list($h, $p) = explode(':', $theserver);
880
        $r = sendMemcacheCommand($h, $p, 'get '.$theKey);
881
        echo <<<EOB
882
        <div class="info"><table cellspacing=0><tbody>
883
            <tr><th>Server<th>Key</th><th>Value</th><th>Delete</th></tr>
884
EOB;
885
        echo "<tr><td class=td-0>",$theserver,"</td><td class=td-0>",$theKey,
886
             " <br/>flag:",$r['VALUE'][$theKey]['stat']['flag'],
887
             " <br/>Size:",bsize($r['VALUE'][$theKey]['stat']['size']),
888
             "</td><td>",chunk_split($r['VALUE'][$theKey]['value'], 40),"</td>",
889
             '<td><a href="',$PHP_SELF,'&op=5&server=',(int)$_GET['server'],'&key=',base64_encode($theKey),"\">Delete</a></td>","</tr>";
890
        echo <<<EOB
891
            </tbody></table>
892
            </div><hr/>
893
EOB;
894
    break;
895
    case 5: // item delete
896
        if (!isset($_GET['key']) || !isset($_GET['server'])) {
897
            echo "No key set!";
898
            break;
899
        }
900
        $theKey = htmlentities(base64_decode($_GET['key']));
901
        $theserver = $MEMCACHE_SERVERS[(int)$_GET['server']];
902
        list($h, $p) = explode(':', $theserver);
903
        $r = sendMemcacheCommand($h, $p, 'delete '.$theKey);
904
        echo 'Deleting '.$theKey.':'.$r;
905
    break;
906
907
   case 6: // flush server
908
        $theserver = $MEMCACHE_SERVERS[(int)$_GET['server']];
909
        $r = flushServer($theserver);
910
        echo 'Flush  '.$theserver.":".$r;
911
   break;
912
}
913
echo getFooter();
914