|
1 | 1 | <?php |
| 2 | + |
| 3 | + // Hides error when no default timezone has been set |
| 4 | + $TZ = @date_default_timezone_get(); |
| 5 | + date_default_timezone_set($TZ); |
| 6 | + |
2 | 7 | define('ENABLE_APC', extension_loaded('apcu') || extension_loaded('apc')); |
3 | 8 | define('ENABLE_OPCACHE', extension_loaded('Zend OPcache')); |
4 | 9 | define('ENABLE_REALPATH', function_exists('realpath_cache_size')); |
| 10 | + define('ENABLE_MEMCACHE', extension_loaded('memcache') || extension_loaded('memcached')); |
5 | 11 |
|
6 | 12 | if (ENABLE_APC) { |
7 | 13 | if (!extension_loaded('apcu')) { |
@@ -34,6 +40,46 @@ function __construct($search = null) { parent::__construct('user', $search); } |
34 | 40 | $realpathCacheTotal = machine_size(ini_get('realpath_cache_size')); |
35 | 41 | } |
36 | 42 |
|
| 43 | + if (ENABLE_MEMCACHE) { |
| 44 | + if (extension_loaded('memcached')) { |
| 45 | + $memcache = new \Memcached(); |
| 46 | + $memcacheVersion = 'memcached'; |
| 47 | + $memcache->addServer('127.0.0.1', 11211); |
| 48 | + $memcache_stats = $memcache->getStats(); |
| 49 | + } else if (extension_loaded('memcache')) { |
| 50 | + $memcache = new \Memcache(); |
| 51 | + $memcacheVersion = 'memcache'; |
| 52 | + $memcache->addServer('127.0.0.1', 11211); |
| 53 | + $memcache_stats = $memcache->getExtendedStats(); |
| 54 | + } |
| 55 | + |
| 56 | + if( is_action('memcache_clear') ) { |
| 57 | + $memcache->flush(); |
| 58 | + redirect('?'); |
| 59 | + } |
| 60 | + |
| 61 | + if( is_action('memcache_delete') && $memcacheVersion == 'memcached' ) { |
| 62 | + $list = memcache_ref(); |
| 63 | + $selector = get_selector(); |
| 64 | + |
| 65 | + foreach ($list as $key => $item) |
| 66 | + if (preg_match($selector, $key)) |
| 67 | + $memcache->delete($key); |
| 68 | + |
| 69 | + redirect( '?action=memcache_select&selector=' . $_GET['selector'] ); |
| 70 | + } |
| 71 | + |
| 72 | + if( is_action('memcache_delete') && $memcacheVersion != 'memcached' ) { |
| 73 | + $memcache->delete($_GET['selector']); |
| 74 | + |
| 75 | + redirect( '?action=memcache_view&selector=' . $_GET['selector'] ); |
| 76 | + } |
| 77 | + } |
| 78 | + |
| 79 | + function val_to_str($value) { |
| 80 | + return htmlentities(var_export($value, true)); |
| 81 | + } |
| 82 | + |
37 | 83 | function is_action($action) { |
38 | 84 | return isset( $_GET['action'] ) && $_GET['action'] == $action; |
39 | 85 | } |
@@ -104,6 +150,66 @@ function apcu_ref() { |
104 | 150 | return array(); |
105 | 151 | } |
106 | 152 |
|
| 153 | + function memcache_mem( $key ) { |
| 154 | + global $memcache_stats; |
| 155 | + |
| 156 | + if( $key == 'free' ) |
| 157 | + return memcache_mem('total') - memcache_mem('used'); |
| 158 | + |
| 159 | + if( $key == 'total') |
| 160 | + $key = 'limit_maxbytes'; |
| 161 | + |
| 162 | + if( $key == 'used' ) |
| 163 | + $key = 'bytes'; |
| 164 | + |
| 165 | + if( $key == 'hash' ) |
| 166 | + $key = 'hash_bytes'; |
| 167 | + |
| 168 | + $result = 0; |
| 169 | + foreach( $memcache_stats as $server ) |
| 170 | + $result += empty($server[$key]) ? 0 : $server[$key]; |
| 171 | + |
| 172 | + return $result; |
| 173 | + } |
| 174 | + |
| 175 | + function memcache_get_key($key, &$found = false) { |
| 176 | + global $memcache; |
| 177 | + global $memcacheVersion; |
| 178 | + |
| 179 | + if (empty($key)) { |
| 180 | + $found = false; |
| 181 | + return false; |
| 182 | + } |
| 183 | + |
| 184 | + if ($memcacheVersion == 'memcache') { |
| 185 | + $val = $memcache->get(array($key)); |
| 186 | + $found = count($val) > 0; |
| 187 | + return $found ? array_pop($val) : false; |
| 188 | + } |
| 189 | + |
| 190 | + $val = $memcache->get($key, null, Memcached::GET_EXTENDED); |
| 191 | + $found = $val !== false; |
| 192 | + return $val['value']; |
| 193 | + } |
| 194 | + |
| 195 | + function memcache_ref() { |
| 196 | + global $memcache; |
| 197 | + |
| 198 | + // Listing keys is not supported using the legacy Memcache module |
| 199 | + // PHP 7 and newer do not support this extension anymore |
| 200 | + if (!extension_loaded('memcached')) |
| 201 | + return array(); |
| 202 | + |
| 203 | + $items = $memcache->getAllKeys(); |
| 204 | + |
| 205 | + $keys = array(); |
| 206 | + foreach( $items as $item ) { |
| 207 | + $keys[$item] = memcache_get_key($item); |
| 208 | + } |
| 209 | + |
| 210 | + return $keys; |
| 211 | + } |
| 212 | + |
107 | 213 | function human_size( $s ) { |
108 | 214 | $size = 'B'; |
109 | 215 | $sizes = array( 'KB', 'MB', 'GB' ); |
@@ -383,7 +489,7 @@ function sort_list(&$list) { |
383 | 489 | <?php if( is_action('apcu_view') ): ?> |
384 | 490 | <div> |
385 | 491 | <h3>Value for <?=htmlentities('"'.$_GET['selector'].'"')?></h3> |
386 | | - <pre><?=htmlentities(var_export(apcu_fetch(urldecode($_GET['selector'])), true)); ?></pre> |
| 492 | + <pre><?=val_to_str(apcu_fetch(urldecode($_GET['selector']))); ?></pre> |
387 | 493 | </div> |
388 | 494 | <?php endif; ?> |
389 | 495 | <?php if( is_action('apcu_select') ): ?> |
@@ -477,6 +583,82 @@ function sort_list(&$list) { |
477 | 583 | <?php endif; ?> |
478 | 584 | </div> |
479 | 585 | <?php endif; ?> |
| 586 | + |
| 587 | + <?php if(ENABLE_MEMCACHE): ?> |
| 588 | + <?php $list = memcache_ref(); ?> |
| 589 | + <h2 id="memcached">Memcached</h2> |
| 590 | + <div> |
| 591 | + <h3>Memory <?=human_size(memcache_mem('used') + memcache_mem('hash'))?> of <?=human_size(memcache_mem('total'))?></h3> |
| 592 | + <div class="full bar green"> |
| 593 | + <div class="orange" style="width: <?=percentage(memcache_mem('used'), memcache_mem('total'))?>%"></div> |
| 594 | + <div class="red" style="width: <?=percentage(memcache_mem('hash'), memcache_mem('total'))?>%"></div> |
| 595 | + </div> |
| 596 | + <div> |
| 597 | + <h3>Actions</h3> |
| 598 | + <form action="?" method="GET"> |
| 599 | + <label>Cache: |
| 600 | + <button name="action" value="memcache_clear">Restart</button> |
| 601 | + </label> |
| 602 | + </form> |
| 603 | + <form action="?" method="GET"> |
| 604 | + <label>Key(s): |
| 605 | + <input name="selector" type="text" value="" placeholder=".*" /> |
| 606 | + </label> |
| 607 | + <?php if ($memcacheVersion == 'memcached'): ?> |
| 608 | + <button type="submit" name="action" value="memcache_select">Select</button> |
| 609 | + <?php else: ?> |
| 610 | + <button type="submit" name="action" value="memcache_view">View</button> |
| 611 | + <?php endif ?> |
| 612 | + <button type="submit" name="action" value="memcache_delete">Delete</button> |
| 613 | + </form> |
| 614 | + </div> |
| 615 | + |
| 616 | + <?php if( is_action('memcache_view') ): ?> |
| 617 | + <?php $value = memcache_get_key($_GET['selector'], $found); ?> |
| 618 | + <div> |
| 619 | + <h3>Value for <?=htmlentities('"'.$_GET['selector'].'"')?></h3> |
| 620 | + <?php if ($found): ?> |
| 621 | + <pre><?=val_to_str($value); ?></pre> |
| 622 | + <?php else: ?> |
| 623 | + <p>Key not found</p> |
| 624 | + <?php endif ?> |
| 625 | + </div> |
| 626 | + <?php endif ?> |
| 627 | + |
| 628 | + <?php if ($memcacheVersion == 'memcached'): ?> |
| 629 | + <?php if( is_action('memcache_select') ): ?> |
| 630 | + <div> |
| 631 | + <table> |
| 632 | + <thead> |
| 633 | + <tr> |
| 634 | + <th><a href="<?=sort_url('key')?>">Key</a></th> |
| 635 | + <th>Action</th> |
| 636 | + </tr> |
| 637 | + </thead> |
| 638 | + <tbody> |
| 639 | + <?php foreach( sort_list($list) as $key => $value ): |
| 640 | + if( !preg_match(get_selector(), $key) ) continue;?> |
| 641 | + <tr> |
| 642 | + <td><?=$key?></td> |
| 643 | + <td> |
| 644 | + <a href="?action=memcache_delete&selector=<?=urlencode('^'.$key.'$')?>">Delete</a> |
| 645 | + <a href="?action=memcache_view&selector=<?=urlencode($key)?>">View</a> |
| 646 | + </td> |
| 647 | + </tr> |
| 648 | + <?php endforeach; ?> |
| 649 | + </tbody> |
| 650 | + </table> |
| 651 | + </div> |
| 652 | + <?php endif; ?> |
| 653 | + <?php else: ?> |
| 654 | + <p style="text-align: center"> |
| 655 | + Legacy <a href="https://pecl.php.net/package/memcache">memcache extension</a> does not support listing keys |
| 656 | + <br /> |
| 657 | + Please install the newer <a href="https://pecl.php.net/package/memcached">memcached extension</a> |
| 658 | + </p> |
| 659 | + <?php endif; ?> |
| 660 | + </div> |
| 661 | + <?php endif; ?> |
480 | 662 | </div> |
481 | 663 | </body> |
482 | 664 | </html> |
0 commit comments