设为首页 收藏本站
查看: 1196|回复: 0

[经验分享] ubuntu下php5.5启用opcache缓存功能

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2014-4-19 21:46:49 | 显示全部楼层 |阅读模式
  opcache,php自身集成的缓存功能。由于我的系统是ubuntu server系统,所以在安装的时候很简单,直接apt-get install 方式安装的php,而且安装的是php5.5的版本,所以系统是自带opcache的,不需要我们再重新安装。
  接下来要配置一下opcache


sudo vi /etc/php5/fpm/conf.d
; configuration for php ZendOpcache module
; priority=05
;zend_extension=opcache.so
opcache.enable=1
opcache.save_comments=1
opcache.memory_consumption=512
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=4000
opcache.revalidate_freq=60
opcache.fast_shutdown=1
opcache.enable_cli=1
opcode.caching=1
opcache.force_restart_timeout=3600
opcache.optimization_level=0xffffffff
opcache.optimization=1
opcache.use_cwd=0
opcache.revalidate_path=0
opcache.enable_file_override=0
  然后修改php.ini文件,在最后添加一行zend_extension=opcache.so
  重启php-fpm或者是nginx,我们可以看到在phpinfo的界面出现了zend opcache的配置信息

wKioL1NSGH7TCBa2AACkBP-xdNo151.jpg
wKiom1NSGKiyqORaAAHQH1afADk624.jpg
好了,到这里我们的opcache已经开始启用了。当然,在上面配置中,可以在php.ini中不加最后一行内容,但是在opcache的配置文件中要把注释去掉,也可以。
  现在看起来还是很别扭,我们可以通过直观的图表形式展现出来

wKioL1NSGZzitLHsAAMUkP8dv5w706.jpg
wKiom1NSGcaQo6-xAAI1cv0YNuQ480.jpg
wKiom1NSGcbDD4T8AAN3PpnkSss971.jpg
好吧,没发过附件,无法上传,好像格式不对,直接上代码吧,网上也有很多的,可以自行百度。
op.php
<?php
/**
* OPcache GUI
*
* A simple but effective single-file GUI for the OPcache PHP extension.
*
* @author Andrew Collington, andy@amnuts.com
* @license MIT, http://acollington.mit-license.org/
*/
if (!function_exists('opcache_get_status')) {
    die('The Zend OPcache extension does not appear to be installed');
}
$settings = array(
    'compress_path_threshold' => 2,
    'used_memory_percentage_high_threshold' => 80,
    'used_memory_percentage_mid_threshold' => 60,
    'allow_invalidate' => true
);
$validPages = array('overview', 'files', 'reset', 'invalidate');
$page = (empty($_GET['page']) || !in_array($_GET['page'], $validPages)
    ? 'overview'
    : strtolower($_GET['page'])
);
if ($page == 'reset') {
    opcache_reset();
    header('Location: ?page=overview');
    exit;
}
if ($page == 'invalidate') {
    $file = (isset($_GET['file']) ? trim($_GET['file']) : null);
    if (!$settings['allow_invalidate'] || !function_exists('opcache_invalidate') || empty($file)) {
        header('Location: ?page=files&error=1');
        exit;
    }
    $success = (int)opcache_invalidate(urldecode($file), true);
    header("Location: ?page=files&success={$success}");
    exit;
}
$opcache_config = opcache_get_configuration();
$opcache_status = opcache_get_status();
$opcache_funcs  = get_extension_funcs('Zend OPcache');
if (!empty($opcache_status['scripts'])) {
    uasort($opcache_status['scripts'], function($a, $b) {
        return $a['hits'] < $b['hits'];
    });
}
function memsize($size, $precision = 3, $space = false)
{
    $i = 0;
    $val = array(' bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
    while (($size / 1024) > 1) {
        $size /= 1024;
        ++$i;
    }
    return sprintf("%.{$precision}f%s%s",
    $size, (($space && $i) ? ' ' : ''), $val[$i]);
}
function rc($at = null)
{
    static $i = 0;
    if ($at !== null) {
        $i = $at;
    } else {
        echo (++$i % 2 ? 'even' : 'odd');
    }
}
$data = array_merge(
    $opcache_status['memory_usage'],
    $opcache_status['opcache_statistics'],
    array(
        'total_memory_size'       => memsize($opcache_config['directives']['opcache.memory_consumption']),
        'used_memory_percentage'  => round(100 * (
            ($opcache_status['memory_usage']['used_memory'] + $opcache_status['memory_usage']['wasted_memory'])
                / $opcache_config['directives']['opcache.memory_consumption'])),
        'hit_rate_percentage'     => round($opcache_status['opcache_statistics']['opcache_hit_rate']),
        'wasted_percentage'       => round($opcache_status['memory_usage']['current_wasted_percentage'], 2),
        'used_memory_size'        => memsize($opcache_status['memory_usage']['used_memory']),
        'free_memory_size'        => memsize($opcache_status['memory_usage']['free_memory']),
        'wasted_memory_size'      => memsize($opcache_status['memory_usage']['wasted_memory']),
        'files_cached'            => number_format($opcache_status['opcache_statistics']['num_cached_scripts']),
        'hits_size'               => number_format($opcache_status['opcache_statistics']['hits']),
        'miss_size'               => number_format($opcache_status['opcache_statistics']['misses']),
        'blacklist_miss_size'     => number_format($opcache_status['opcache_statistics']['blacklist_misses']),
        'num_cached_keys_size'    => number_format($opcache_status['opcache_statistics']['num_cached_keys']),
        'max_cached_keys_size'    => number_format($opcache_status['opcache_statistics']['max_cached_keys']),
    )
);
$threshold = '';
if ($data['used_memory_percentage'] >= $settings['used_memory_percentage_high_threshold']) {
    $threshold = ' high';
} elseif ($data['used_memory_percentage'] >= $settings['used_memory_percentage_mid_threshold']) {
    $threshold = ' mid';
}
if (!empty($_SERVER['HTTP_X_REQUESTED_WITH'])
    && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest'
) {
    echo json_encode($data);
    exit;
}
$host = (function_exists('gethostname')
    ? gethostname()
    : (php_uname('n')
        ?: (empty($_SERVER['SERVER_NAME'])
            ? $_SERVER['HOST_NAME']
            : $_SERVER['SERVER_NAME']
        )
    )
);
?>
<!doctype html>
<html>
<head>
    <meta charset="UTF-8"/>
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
    <link href="//fonts.googleapis.com/css?family=Roboto" rel="stylesheet" type="text/css">
    <style type="text/css">
        html{font-family:sans-serif;font-size:100%;line-height:1.2;padding:2em;}
        body {font-size:75%;}
        .container{overflow:auto;width:100%;position:relative;}
        #info{margin-right:290px;}
        #counts{position:absolute;top:0;right:0;width:280px;}
        #counts div{
            padding:1em;
            margin-bottom:1em;
            border-radius: 5px;
            background-image: linear-gradient(bottom, #B7C8CC 21%, #D5DEE0 60%, #E0ECEF 80%);
            background-image: -webkit-gradient(linear,left bottom,left top,color-stop(0.21, #B7C8CC),color-stop(0.6, #D5DEE0),color-stop(0.8, #E0ECEF));
        }
        #counts p {text-align:center;}
        #counts div.values p {text-align:left;}
        #counts p span{font-family:'Roboto',sans-serif;}
        #counts p span.large{display:block;line-height:90%;font-size:800%;}
        table { margin: 0 0 1em 0; border-collapse: collapse; border-color: #fff; width: 100%; }
        table caption { text-align: left; font-size: 1.5em; }      
        table tr { background-color: #99D0DF; border-color: #fff; }
        table th { text-align: left; padding: 6px; background-color: #0BA0C8; color: #fff; border-color: #fff; }
        table td { padding: 4px 6px; line-height: 1.4em; vertical-align: top; border-color: #fff; }
        table tr.odd { background-color: #EFFEFF; }
        table tr.even { background-color: #E0ECEF; }
        table tr.highlight { background-color: #61C4DF; }
        td.pathname p { margin-bottom: 0.25em; }
        .wsnw { white-space: nowrap; }
        .low{color:#000000;}
        .mid{color:#550000;}
        .high{color:#FF0000;}
        .invalid{color:#FF4545;}
        span.showmore span.button {
            display: inline-block;
            margin-right: 5px;
            position: relative;
            top: -1px;
            color: #333333;
            background: none repeat scroll 0 0 #DDDDDD;
            border-radius: 2px 2px 2px 2px;
            font-size: 12px;
            font-weight: bold;
            height: 12px;
            line-height: 6px;
            padding: 0 5px;
            vertical-align: middle;
            cursor: pointer;
        }      
        a.button {
            text-decoration: none;
            font-size: 110%;
            color: #292929;
            padding: 10px 26px;
            background: -moz-linear-gradient(top, #ffffff 0%, #b4b7b8);
            background: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#b4b7b8));
            -moz-border-radius: 6px;
            -webkit-border-radius: 6px;
            border-radius: 6px;
            border: 1px solid #a1a1a1;
            text-shadow: 0px -1px 0px rgba(000,000,000,0), 0px 1px 0px rgba(255,255,255,0.4);
            margin: 0 1em;
            white-space: nowrap;
        }      
        span.showmore span.button:hover {
            background-color: #CCCCCC;
        }
        @media screen and (max-width: 700px) {
            #info{margin-right:auto;}
            #counts{position:relative;display:block;margin-bottom:2em;width:100%;}
        }
        @media screen and (max-width: 550px) {
            a.button{display:block;margin-bottom:2px;}
            #frmFilter{width:99% !important;}
        }
    </style>
</head>
<body>
    <div style="text-align:center;margin-bottom:2em;">
        <p>
            <a href="?page=overview" class="button">Overview</a>
            <a href="?page=files" class="button">File usage</a>
            <a href="?page=reset" class="button"  confirm('Are you sure you want to reset the cache?');">Reset cache</a>
        </p>
    </div>
    <?php if ($page == 'overview'): ?>
    <h2>Overview</h2>
    <div class="container">
        <div id="counts">
            <div>
                <p><span class="large <?php echo $threshold; ?>"><span class="realtime" data-value="used_memory_percentage"><?php echo $data['used_memory_percentage']; ?></span>%</span><br/>memory usage</p>
            </div>
            <div>
                <p><span class="large"><span class="realtime" data-value="hit_rate"><?php echo $data['hit_rate_percentage']; ?></span>%</span><br/>hit rate</p>
            </div>
            <div class="values">
                <p><b>total memory:</b> <span data-value="total_memory_size"><?php echo $data['total_memory_size']; ?></span></p>
                <p><b>used memory:</b> <span class="realtime" data-value="used_memory_size"><?php echo $data['used_memory_size']; ?></span></p>
                <p><b>free memory:</b> <span class="realtime" data-value="free_memory_size"><?php echo $data['free_memory_size']; ?></span></p>
                <p><b>wasted memory:</b> <span class="realtime" data-value="wasted_memory_size"><?php echo $data['wasted_memory_size']; ?></span> (<span class="realtime" data-value="wasted_percentage"><?php echo $data['wasted_percentage']; ?></span>%)</p>
                <p><b>number of cached files:</b> <span class="realtime" data-value="files_cached"><?php echo $data['files_cached']; ?></span></p>
                <p><b>number of hits:</b> <span class="realtime" data-value="hits_size"><?php echo $data['hits_size']; ?></span></p>
                <p><b>number of misses:</b> <span class="realtime" data-value="miss_size"><?php echo $data['miss_size']; ?></span></p>
                <p><b>blacklist misses:</b> <span class="realtime" data-value="blacklist_miss_size"><?php echo $data['blacklist_miss_size']; ?></span></p>
                <p><b>number of cached keys:</b> <span class="realtime" data-value="num_cached_keys_size"><?php echo $data['num_cached_keys_size']; ?></span></p>
                <p><b>max cached keys:</b> <span class="realtime" data-value="max_cached_keys_size"><?php echo $data['max_cached_keys_size']; ?></span></p>
            </div>
            <br />
            <p><a href="#" id="toggleRealtime">Enable real-time update of stats</a></p>
        </div>
        <div id="info">

            <table>
                <tr><th colspan="2">General info</th></tr>
                <tr class="<?php rc(); ?>">
                    <td>Zend OPcache</td>
                    <td><?php echo $opcache_config['version']['version']; ?></td>
                </tr>
                <tr class="<?php rc(); ?>">
                    <td>PHP</td>
                    <td><?php echo phpversion(); ?></td>
                </tr>
                <tr class="<?php rc(); ?>">  
                    <td>Host</td>
                    <td><?php echo $host; ?></td>
                </tr>
                <?php if (!empty($_SERVER['SERVER_SOFTWARE'])): ?>
                <tr class="<?php rc(); ?>">
                    <td>Server Software</td>
                    <td><?php echo $_SERVER['SERVER_SOFTWARE']; ?></td>
                </tr>
                <?php endif; ?>
                <tr class="<?php rc(); ?>">
                    <td>Start time</td>
                    <td><?php echo date_format(date_create("@{$data['start_time']}"), 'Y-m-d H:i:s'); ?></td>
                </tr>
                <tr class="<?php rc(); ?>">
                    <td>Last reset</td>
                    <td><?php echo ($data['last_restart_time'] == 0
                            ? '<em>never</em>'
                            : date_format(date_create("@{$data['last_restart_time']}"), 'Y-m-d H:i:s')); ?></td>
                </tr>
            </table>

            <table>
                <tr><th colspan="2">Directives</th></tr>
                <?php ksort($opcache_config['directives']); ?>
                <?php rc(0); foreach ($opcache_config['directives'] as $d => $v): ?>
                <tr class="<?php rc(); ?>">
                    <td><span title="<?php echo $d; ?>"><?php echo str_replace(array('opcache.', '_'), array('', ' '), $d); ?></span></td>
                    <td><?php echo (is_bool($v)
                        ? ($v ? '<i>true</i>' : '<i>false</i>')
                        : (empty($v) ? '<i>no value</i>' : $v)); ?></td>
                </tr>
                <?php endforeach; ?>
            </table>

            <table>
                <tr><th>Available functions</th></tr>
                <?php rc(0); foreach ($opcache_funcs as $f): ?>
                <tr class="<?php rc(); ?>">
                    <td><a href="http://php.net/<?php echo $f; ?>" title="View manual page" target="_blank"><?php echo $f; ?></td>
                </tr>
                <?php endforeach; ?>
            </table>
            <br style="clear:both;" />
        </div>
    </div>
    <script type="text/javascript">
        $(function(){
            var realtime = false;
            function ping() {
                $.ajax({
                    url: "#",
                    dataType: "json",
                    cache: false,
                    success: function(data){
                        $('.realtime').each(function(){
                            $(this).text(data[$(this).attr('data-value')]);
                        });
                    }
                });
            }
            $('#toggleRealtime').click(function(){
                if (realtime === false) {
                    realtime = setInterval(function(){ping()}, 5000);
                    $(this).text('Disable real-time update of stats');
                } else {
                    clearInterval(realtime);
                    realtime = false;
                    $(this).text('Enable real-time update of stats');
                }
            });
        });
    </script>
    <?php endif; ?>
    <?php if ($page == 'files'): ?>
    <h2>File usage</h2>
    <p><label>Start typing to filter on script path<br/><input type="text" style="width:40em;" name="filter" id="frmFilter" /><label></p>
    <div class="container">
        <h3><?php echo $data['files_cached']; ?> file<?php echo ($data['files_cached'] == 1 ? '' : 's'); ?> cached <span id="filterShowing"></span></h3>
        <table>
        <tr>
            <th>Script</th>
            <th>Details</th>
        </tr>
        <?php rc(0); foreach ($opcache_status['scripts'] as $s): ?>
        <tr class="<?php rc(); ?>">
            <td class="pathname"><p><?php
                $base  = basename($s['full_path']);
                $parts = array_filter(explode(DIRECTORY_SEPARATOR, dirname($s['full_path'])));
                if (!empty($settings['compress_path_threshold'])) {
                    echo '<span class="showmore"><span class="button">…</span><span class="text" style="display:none;">' . DIRECTORY_SEPARATOR;
                    echo join(DIRECTORY_SEPARATOR, array_slice($parts, 0, $settings['compress_path_threshold'])) . DIRECTORY_SEPARATOR;
                    echo '</span>';
                    echo join(DIRECTORY_SEPARATOR, array_slice($parts, $settings['compress_path_threshold']));
                    if (count($parts) > $settings['compress_path_threshold']) {
                        echo DIRECTORY_SEPARATOR;
                    }
                    echo "{$base}</span>";
                } else {
                    echo htmlentities($s['full_path'], ENT_COMPAT, 'UTF-8');
                }
                ?></p>
                <?php if ($settings['allow_invalidate'] && function_exists('opcache_invalidate')): ?>
                <a href="?page=invalidate&file=<?php echo urlencode($s['full_path']); ?>">Force file invalidation</a>
                <?php endif; ?>
            </td>
            <td>
                <p>
                    hits: <?php echo $s['hits']; ?>,
                    memory: <?php echo memsize($s['memory_consumption']); ?><br />
                    last used: <?php echo date_format(date_create($s['last_used']), 'Y-m-d H:i:s'); ?>
                    <?php if ($s['timestamp'] === 0): ?>
                    <br /><i class="invalid">has been invalidated</i>
                    <?php endif; ?>
                </p>
            </td>
        </tr>
        <?php endforeach; ?>
        </table>
    </div>
    <script type="text/javascript">
        $(function(){
            $('span.showmore span.button').click(function(){
                if ($(this).next().is(":visible")) {
                    $(this).next().hide();
                    $(this).css('padding-top', '0').text('…');
                } else {
                    $(this).next().show();
                    $(this).css('padding-top', '2px').text('');
                }
            });
            $('.container table').bind('paint', function(event, params) {
                var trs = $('tr:visible', $(this)).not(':first');
                trs.removeClass('odd even')
                   .filter(':odd').addClass('odd')
                   .end()
                   .filter(':even').addClass('even');
                $('#filterShowing').text(($('#frmFilter').val().length
                    ? trs.length + ' showing due to filter'
                    : ''
                ));
            });
            $('#frmFilter').bind('keyup', function(event){
                $('td.pathname p').each(function(index){
                    if ($(this).text().toLowerCase().indexOf($('#frmFilter').val().toLowerCase()) == -1) {
                        $(this).closest('tr').hide();
                    } else {
                        $(this).closest('tr').show();
                    }
                });
                $('.container table').trigger('paint');
            });
        });
    </script>
    <?php endif; ?>
</body>
</html>
ocp.php


<?php
/*
OCP - Opcache Control Panel   (aka Zend Optimizer+ Control Panel for PHP)
Author: _ck_   (with contributions by GK, stasilok)
Version: 0.1.6
Free for any kind of use or modification, I am not responsible for anything, please share your improvements
* revision history
0.1.6  2013-04-12  moved meta to footer so graphs can be higher and reduce clutter
0.1.5  2013-04-12  added graphs to visualize cache state, please report any browser/style bugs
0.1.4  2013-04-09  added "recheck" to update files when using large revalidate_freq (or validate_timestamps=Off)
0.1.3  2013-03-30  show host and php version, can bookmark with hashtag ie. #statistics - needs new layout asap
0.1.2  2013-03-25  show optimization levels, number formatting, support for start_time in 7.0.2
0.1.1  2013-03-18  today Zend completely renamed Optimizer+ to OPcache, adjusted OCP to keep working
0.1.0  2013-03-17  added group/sort indicators, replaced "accelerator_" functions with "opcache_"
0.0.6  2013-03-16  transition support as Zend renames product and functions for PHP 5.5 (stasilok)
0.0.5  2013-03-10  added refresh button (GK)
0.0.4  2013-02-18  added file grouping and sorting (click on headers) - code needs cleanup but gets the job done
0.0.2  2013-02-14  first public release
* known problems/limitations:
Unlike APC, the Zend OPcache API
- cannot determine when a file was put into the cache
- cannot change settings on the fly
- cannot protect opcache functions by restricting execution to only specific scripts/paths
* todo:
Extract variables for prefered ordering and better layout instead of just dumping into tables
File list filter
*/
// ini_set('display_errors',1); error_reporting(-1);
if ( count(get_included_files())>1 || php_sapi_name()=='cli' || empty($_SERVER['REMOTE_ADDR']) ) { die; }  // weak block against indirect access
$time=time();
define('CACHEPREFIX',function_exists('opcache_reset')?'opcache_':(function_exists('accelerator_reset')?'accelerator_':''));
if ( !empty($_GET['RESET']) ) {
    if ( function_exists(CACHEPREFIX.'reset') ) { call_user_func(CACHEPREFIX.'reset'); }
    header( 'Location: '.str_replace('?'.$_SERVER['QUERY_STRING'],'',$_SERVER['REQUEST_URI']) );
    exit;
}
if ( !empty($_GET['RECHECK']) ) {
    if ( function_exists(CACHEPREFIX.'invalidate') ) {
        $recheck=trim($_GET['RECHECK']); $files=call_user_func(CACHEPREFIX.'get_status');
        if (!empty($files['scripts'])) {
            foreach ($files['scripts'] as $file=>$value) {
                if ( $recheck==='1' || strpos($file,$recheck)===0 )  call_user_func(CACHEPREFIX.'invalidate',$file);
            }
        }
        header( 'Location: '.str_replace('?'.$_SERVER['QUERY_STRING'],'',$_SERVER['REQUEST_URI']) );
    } else { echo 'Sorry, this feature requires Zend Opcache newer than April 8th 2013'; }
    exit;
}
?><!DOCTYPE html>
<html>
<head>
    <title>OCP - Opcache Control Panel</title>
    <meta name="ROBOTS" content="NOINDEX,NOFOLLOW,NOARCHIVE" />
<style type="text/css">
    body {background-color: #fff; color: #000;}
    body, td, th, h1, h2 {font-family: sans-serif;}
    pre {margin: 0px; font-family: monospace;}
    a:link,a:visited {color: #000099; text-decoration: none;}
    a:hover {text-decoration: underline;}
    table {border-collapse: collapse;}
    .center {text-align: center;}
    .center table { margin-left: auto; margin-right: auto; text-align: left;}
    .center th { text-align: center !important; }
    .middle {vertical-align:middle;}
    td, th { border: 1px solid #000; font-size: 75%; vertical-align: baseline;}
    h1 {font-size: 150%;}
    h2 {font-size: 125%;}
    .p {text-align: left;}
    .e {background-color: #ccccff; font-weight: bold; color: #000; width:50%; white-space:nowrap;}
    .h {background-color: #9999cc; font-weight: bold; color: #000;}
    .v {background-color: #cccccc; color: #000;}
    .vr {background-color: #cccccc; text-align: right; color: #000; white-space: nowrap;}
    .b {font-weight:bold;}
    .white, .white a {color:#fff;}
    img {float: right; border: 0px;}
    hr {width: 600px; background-color: #cccccc; border: 0px; height: 1px; color: #000;}
    .meta, .small {font-size: 75%; }
    .meta {margin: 2em 0;}
    .meta a, th a {padding: 10px; white-space:nowrap; }
    .buttons {margin:0 0 1em;}
    .buttons a {margin:0 15px; background-color: #9999cc; color:#fff; text-decoration:none; padding:1px; border:1px solid #000; display:inline-block; width:5em; text-align:center;}
    #files td.v a {font-weight:bold; color:#9999cc; margin:0 10px 0 5px; text-decoration:none; font-size:120%;}
    #files td.v a:hover {font-weight:bold; color:#ee0000;}
    .graph {display:inline-block; width:145px; margin:1em 0 1em 1px; border:0; vertical-align:top;}
    .graph table {width:100%; height:150px; border:0; padding:0; margin:5px 0 0 0; position:relative;}
    .graph td {vertical-align:middle; border:0; padding:0 0 0 5px;}
    .graph .bar {width:25px; text-align:right; padding:0 2px; color:#fff;}
    .graph .total {width:34px; text-align:center; padding:0 5px 0 0;}
    .graph .total div {border:1px dashed #888; border-right:0; height:99%; width:12px; position:absolute; bottom:0; left:17px; z-index:-1;}
    .graph .total span {background:#fff; font-weight:bold;}
    .graph .actual {text-align:right; font-weight:bold; padding:0 5px 0 0;}
    .graph .red {background:#ee0000;}
    .graph .green {background:#00cc00;}
    .graph .brown {background:#8B4513;}
</style>
<!--[if lt IE 9]><script type="text/javascript" defer="defer">
window. i,t=document.getElementsByTagName('table');for(i=0;i<t.length;i++){if(t.parentNode.className=='graph')t.style.height=150-(t.clientHeight-150)+'px';}}
</script><![endif]-->
</head>
<body>
<div class="center">
<h1><a href="?">Opcache Control Panel</a></h1>
<div class="buttons">
    <a href="?ALL=1">Details</a>
    <a href="?FILES=1&GROUP=2&SORT=3">Files</a>
    <a href="?RESET=1"  confirm('RESET cache ?')">Reset</a>
    <?php if ( function_exists(CACHEPREFIX.'invalidate') ) { ?>
    <a href="?RECHECK=1"  confirm('Recheck all files in the cache ?')">Recheck</a>
    <?php } ?>
    <a href="?">Refresh</a>
</div>
<?php
if ( !function_exists(CACHEPREFIX.'get_status') ) { echo '<h2>Opcache not detected?</h2>'; die; }
if ( !empty($_GET['FILES']) ) { echo '<h2>files cached</h2>'; files_display(); echo '</div></body></html>'; exit; }
if ( !(isset($_REQUEST['GRAPHS']) && !$_REQUEST['GRAPHS']) && CACHEPREFIX=='opcache_') { graphs_display(); if ( !empty($_REQUEST['GRAPHS']) ) { exit; } }
ob_start(); phpinfo(8); $phpinfo = ob_get_contents(); ob_end_clean();        // some info is only available via phpinfo? sadly buffering capture has to be used
if ( !preg_match( '/module\_Zend (Optimizer\+|OPcache).+?(\<table[^>]*\>.+?\<\/table\>).+?(\<table[^>]*\>.+?\<\/table\>)/s', $phpinfo, $opcache) ) { }  // todo
if ( function_exists(CACHEPREFIX.'get_configuration') ) { echo '<h2>general</h2>'; $configuration=call_user_func(CACHEPREFIX.'get_configuration'); }
$host=function_exists('gethostname')?@gethostname():@php_uname('n'); if (empty($host)) { $host=empty($_SERVER['SERVER_NAME'])?$_SERVER['HOST_NAME']:$_SERVER['SERVER_NAME']; }
$version=array('Host'=>$host);
$version['PHP Version']='PHP '.(defined('PHP_VERSION')?PHP_VERSION:'???').' '.(defined('PHP_SAPI')?PHP_SAPI:'').' '.(defined('PHP_OS')?' '.PHP_OS:'');
$version['Opcache Version']=empty($configuration['version']['version'])?'???':$configuration['version'][CACHEPREFIX.'product_name'].' '.$configuration['version']['version'];
print_table($version);
if ( !empty($opcache[2]) ) { echo preg_replace('/\<tr\>\<td class\="e"\>[^>]+\<\/td\>\<td class\="v"\>[0-9\,\. ]+\<\/td\>\<\/tr\>/','',$opcache[2]); }
if ( function_exists(CACHEPREFIX.'get_status') && $status=call_user_func(CACHEPREFIX.'get_status') ) {
    $uptime=array();
    if ( !empty($status[CACHEPREFIX.'statistics']['start_time']) ) {
        $uptime['uptime']=time_since($time,$status[CACHEPREFIX.'statistics']['start_time'],1,'');
    }
    if ( !empty($status[CACHEPREFIX.'statistics']['last_restart_time']) ) {
        $uptime['last_restart']=time_since($time,$status[CACHEPREFIX.'statistics']['last_restart_time']);     
    }
    if (!empty($uptime)) {print_table($uptime);}

    if ( !empty($status['cache_full']) ) { $status['memory_usage']['cache_full']=$status['cache_full']; }

    echo '<h2 id="memory">memory</h2>';
    print_table($status['memory_usage']);
    unset($status[CACHEPREFIX.'statistics']['start_time'],$status[CACHEPREFIX.'statistics']['last_restart_time']);
    echo '<h2 id="statistics">statistics</h2>';
    print_table($status[CACHEPREFIX.'statistics']);
}
if ( empty($_GET['ALL']) ) { meta_display(); exit; }

if ( !empty($configuration['blacklist']) ) { echo '<h2 id="blacklist">blacklist</h2>'; print_table($configuration['blacklist']); }
if ( !empty($opcache[3]) ) { echo '<h2 id="runtime">runtime</h2>'; echo $opcache[3]; }
$name='zend opcache'; $functions=get_extension_funcs($name);
if (!$functions) { $name='zend optimizer+'; $functions=get_extension_funcs($name); }
if ($functions) { echo '<h2 id="functions">functions</h2>'; print_table($functions);  } else { $name=''; }
$level=trim(CACHEPREFIX,'_').'.optimization_level';
if (isset($configuration['directives'][$level])) {
    echo '<h2 id="optimization">optimization levels</h2>';   
    $levelset=strrev(base_convert($configuration['directives'][$level], 10, 2));
    $levels=array(
        1=>'<a href="http://wikipedia.org/wiki/Common_subexpression_elimination">Constants subexpressions elimination</a> (CSE) true, false, null, etc.<br />Optimize series of ADD_STRING / ADD_CHAR<br />Convert CAST(IS_BOOL,x) into BOOL(x)<br />Convert <a href="http://www.php.net/manual/internals2.opcodes.init-fcall-by-name.php">INIT_FCALL_BY_NAME</a> + <a href="http://www.php.net/manual/internals2.opcodes.do-fcall-by-name.php">DO_FCALL_BY_NAME</a> into <a href="http://www.php.net/manual/internals2.opcodes.do-fcall.php">DO_FCALL</a>',
        2=>'Convert constant operands to expected types<br />Convert conditional <a href="http://php.net/manual/internals2.opcodes.jmp.php">JMP</a>  with constant operands<br />Optimize static <a href="http://php.net/manual/internals2.opcodes.brk.php">BRK</a> and <a href="<a href="http://php.net/manual/internals2.opcodes.cont.php">CONT</a>',
        3=>'Convert $a = $a + expr into $a += expr<br />Convert $a++ into ++$a<br />Optimize series of <a href="http://php.net/manual/internals2.opcodes.jmp.php">JMP</a>',
        4=>'PRINT and ECHO optimization (<a href="https://github.com/zend-dev/ZendOptimizerPlus/issues/73">defunct</a>)',
    5=>'Block Optimization - most expensive pass<br />Performs many different optimization patterns based on <a href="http://wikipedia.org/wiki/Control_flow_graph">control flow graph</a> (CFG)',
    9=>'Optimize <a href="http://wikipedia.org/wiki/Register_allocation">register allocation</a> (allows re-usage of temporary variables)',
    10=>'Remove NOPs'
    );
    echo '<table width="600" border="0" cellpadding="3"><tbody><tr class="h"><th>Pass</th><th>Description</th></tr>';
    foreach ($levels as $pass=>$description) {
        $disabled=substr($levelset,$pass-1,1)!=='1' || $pass==4 ? ' white':'';
        echo '<tr><td class="v center middle'.$disabled.'">'.$pass.'</td><td class="v'.$disabled.'">'.$description.'</td></tr>';
    }
    echo '</table>';
}
if ( isset($_GET['DUMP']) ) {
    if ($name) { echo '<h2 id="ini">ini</h2>'; print_table(ini_get_all($name,true)); }
    foreach ($configuration as $key=>$value) { echo '<h2>',$key,'</h2>'; print_table($configuration[$key]); }
    exit;
}
meta_display();
echo '</div></body></html>';
exit;
function time_since($time,$original,$extended=0,$text='ago') {
    $time =  $time - $original;
    $day = $extended? floor($time/86400) : round($time/86400,0);
    $amount=0; $unit='';
    if ( $time < 86400) {
        if ( $time < 60)     { $amount=$time; $unit='second'; }
        elseif ( $time < 3600) { $amount=floor($time/60); $unit='minute'; }
        else                { $amount=floor($time/3600); $unit='hour'; }         
    }
    elseif ( $day < 14)  { $amount=$day; $unit='day'; }
    elseif ( $day < 56)  { $amount=floor($day/7); $unit='week'; }
    elseif ( $day < 672) { $amount=floor($day/30); $unit='month'; }
    else {            $amount=intval(2*($day/365))/2; $unit='year'; }

    if ( $amount!=1) {$unit.='s';}
    if ($extended && $time>60) { $text=' and '.time_since($time,$time<86400?($time<3600?$amount*60:$amount*3600):$day*86400,0,'').$text; }

    return $amount.' '.$unit.' '.$text;
}
function print_table($array,$headers=false) {
    if ( empty($array) || !is_array($array) ) {return;}
    echo '<table border="0" cellpadding="3" width="600">';
    if (!empty($headers)) {
        if (!is_array($headers)) {$headers=array_keys(reset($array));}
        echo '<tr class="h">';
        foreach ($headers as $value) { echo '<th>',$value,'</th>'; }
        echo '</tr>';           
    }
    foreach ($array as $key=>$value) {
            echo '<tr>';
            if ( !is_numeric($key) ) {
                $key=ucwords(str_replace('_',' ',$key));
                echo '<td class="e">',$key,'</td>';
                if ( is_numeric($value) ) {
                        if ( $value>1048576) { $value=round($value/1048576,1).'M'; }
                        elseif ( is_float($value) ) { $value=round($value,1); }
                }
            }
            if ( is_array($value) ) {
                foreach ($value as $column) {
                    echo '<td class="v">',$column,'</td>';
                }
                echo '</tr>';
            }
            else { echo '<td class="v">',$value,'</td></tr>'; }
    }
    echo '</table>';
}
function files_display() {        
    $status=call_user_func(CACHEPREFIX.'get_status');
    if ( empty($status['scripts']) ) {return;}
    if ( isset($_GET['DUMP']) ) { print_table($status['scripts']); exit;}
        $time=time(); $sort=0;
    $nogroup=preg_replace('/\&?GROUP\=[\-0-9]+/','',$_SERVER['REQUEST_URI']);
    $nosort=preg_replace('/\&?SORT\=[\-0-9]+/','',$_SERVER['REQUEST_URI']);
    $group=empty($_GET['GROUP'])?0:intval($_GET['GROUP']); if ( $group<0 || $group>9) { $group=1;}
    $groupset=array_fill(0,9,''); $groupset[$group]=' class="b" ';

    echo '<div class="meta">
        <a ',$groupset[0],'href="',$nogroup,'">ungroup</a> |
        <a ',$groupset[1],'href="',$nogroup,'&GROUP=1">1</a> |
        <a ',$groupset[2],'href="',$nogroup,'&GROUP=2">2</a> |
        <a ',$groupset[3],'href="',$nogroup,'&GROUP=3">3</a> |
        <a ',$groupset[4],'href="',$nogroup,'&GROUP=4">4</a> |
        <a ',$groupset[5],'href="',$nogroup,'&GROUP=5">5</a>
    </div>';

    if ( !$group ) { $files =& $status['scripts']; }
    else {   
        $files=array();
        foreach ($status['scripts'] as $data) {
            if ( preg_match('@^[/]([^/]+[/]){'.$group.'}@',$data['full_path'],$path) ) {
                if ( empty($files[$path[0]])) { $files[$path[0]]=array('full_path'=>'','files'=>0,'hits'=>0,'memory_consumption'=>0,'last_used_timestamp'=>'','timestamp'=>''); }
                $files[$path[0]]['full_path']=$path[0];
                $files[$path[0]]['files']++;
                $files[$path[0]]['memory_consumption']+=$data['memory_consumption'];                     
                $files[$path[0]]['hits']+=$data['hits'];
                if ( $data['last_used_timestamp']>$files[$path[0]]['last_used_timestamp']) {$files[$path[0]]['last_used_timestamp']=$data['last_used_timestamp'];}
                if ( $data['timestamp']>$files[$path[0]]['timestamp']) {$files[$path[0]]['timestamp']=$data['timestamp'];}                        
            }                 
        }
    }

    if ( !empty($_GET['SORT']) ) {
        $keys=array(
            'full_path'=>SORT_STRING,
            'files'=>SORT_NUMERIC,
            'memory_consumption'=>SORT_NUMERIC,
            'hits'=>SORT_NUMERIC,
            'last_used_timestamp'=>SORT_NUMERIC,
            'timestamp'=>SORT_NUMERIC
        );
        $titles=array('','path',$group?'files':'','size','hits','last used','created');
        $offsets=array_keys($keys);
        $key=intval($_GET['SORT']);
        $direction=$key>0?1:-1;
        $key=abs($key)-1;
        $key=isset($offsets[$key])&&!($key==1&&empty($group))?$offsets[$key]:reset($offsets);
        $sort=array_search($key,$offsets)+1;
        $sortflip=range(0,7); $sortflip[$sort]=-$direction*$sort;
        if ( $keys[$key]==SORT_STRING) {$direction=-$direction; }
        $arrow=array_fill(0,7,''); $arrow[$sort]=$direction>0?' &#x25BC;':' &#x25B2;';
        $direction=$direction>0?SORT_DESC:SORT_ASC;
        $column=array(); foreach ($files as $data) { $column[]=$data[$key]; }
        array_multisort($column, $keys[$key], $direction, $files);
    }
    echo '<table border="0" cellpadding="3" width="960" id="files">
                <tr class="h">';
         foreach ($titles as $column=>$title) {
            if ($title) echo '<th><a href="',$nosort,'&SORT=',$sortflip[$column],'">',$title,$arrow[$column],'</a></th>';
         }
         echo ' </tr>';
        foreach ($files as $data) {
            echo '<tr>
                    <td class="v" nowrap><a title="recheck" href="?RECHECK=',rawurlencode($data['full_path']),'">x</a>',$data['full_path'],'</td>',
                    ($group?'<td class="vr">'.number_format($data['files']).'</td>':''),
                    '<td class="vr">',number_format(round($data['memory_consumption']/1024)),'K</td>',
                    '<td class="vr">',number_format($data['hits']),'</td>',                              
                    '<td class="vr">',time_since($time,$data['last_used_timestamp']),'</td>',
                    '<td class="vr">',empty($data['timestamp'])?'':time_since($time,$data['timestamp']),'</td>
                </tr>';
    }
    echo '</table>';
}
function graphs_display() {
    $graphs=array();
    $colors=array('green','brown','red');
    $primes=array(223, 463, 983, 1979, 3907, 7963, 16229, 32531, 65407, 130987);
    $configuration=call_user_func(CACHEPREFIX.'get_configuration');
    $status=call_user_func(CACHEPREFIX.'get_status');
    $graphs['memory']['total']=$configuration['directives']['opcache.memory_consumption'];
    $graphs['memory']['free']=$status['memory_usage']['free_memory'];
    $graphs['memory']['used']=$status['memory_usage']['used_memory'];
    $graphs['memory']['wasted']=$status['memory_usage']['wasted_memory'];
    $graphs['keys']['total']=$status[CACHEPREFIX.'statistics']['max_cached_keys'];
    foreach ($primes as $prime) { if ($prime>=$graphs['keys']['total']) { $graphs['keys']['total']=$prime; break;} }
    $graphs['keys']['free']=$graphs['keys']['total']-$status[CACHEPREFIX.'statistics']['num_cached_keys'];
    $graphs['keys']['scripts']=$status[CACHEPREFIX.'statistics']['num_cached_scripts'];
    $graphs['keys']['wasted']=$status[CACHEPREFIX.'statistics']['num_cached_keys']-$status[CACHEPREFIX.'statistics']['num_cached_scripts'];
    $graphs['hits']['total']=0;
    $graphs['hits']['hits']=$status[CACHEPREFIX.'statistics']['hits'];
    $graphs['hits']['misses']=$status[CACHEPREFIX.'statistics']['misses'];
    $graphs['hits']['blacklist']=$status[CACHEPREFIX.'statistics']['blacklist_misses'];
    $graphs['hits']['total']=array_sum($graphs['hits']);
    $graphs['restarts']['total']=0;
    $graphs['restarts']['manual']=$status[CACHEPREFIX.'statistics']['manual_restarts'];
    $graphs['restarts']['keys']=$status[CACHEPREFIX.'statistics']['hash_restarts'];
    $graphs['restarts']['memory']=$status[CACHEPREFIX.'statistics']['oom_restarts'];
    $graphs['restarts']['total']=array_sum($graphs['restarts']);
    foreach ( $graphs as $caption=>$graph) {
    echo '<div class="graph"><div class="h">',$caption,'</div><table border="0" cellpadding="0" cellspacing="0">';
    foreach ($graph as $label=>$value) {
        if ($label=='total') { $key=0; $total=$value; $totaldisplay='<td rowspan="3" class="total"><span>'.($total>999999?round($total/1024/1024).'M':($total>9999?round($total/1024).'K':$total)).'</span><div></div></td>'; continue;}
        $percent=$total?floor($value*100/$total):''; $percent=!$percent||$percent>99?'':$percent.'%';
        echo '<tr>',$totaldisplay,'<td class="actual">', ($value>999999?round($value/1024/1024).'M':($value>9999?round($value/1024).'K':$value)),'</td><td class="bar ',$colors[$key],'" height="',$percent,'">',$percent,'</td><td>',$label,'</td></tr>';
        $key++; $totaldisplay='';
    }
    echo '</table></div>',"\n";
    }
}
function meta_display() {
?>
<div class="meta">
    <a href="http://files.zend.com/help/Zend-Server-6/content/zendoptimizerplus.html">directives guide</a> |
    <a href="http://files.zend.com/help/Zend-Server-6/content/zend_optimizer+_-_php_api.htm">functions guide</a> |
    <a href="https://wiki.php.net/rfc/optimizerplus">wiki.php.net</a> |
    <a href="http://pecl.php.net/package/ZendOpcache">pecl</a> |
    <a href="https://github.com/zend-dev/ZendOptimizerPlus/">Zend source</a> |   
    <a href="https://gist.github.com/ck-on/4959032/?ocp.php">OCP latest</a>
</div>
<?php
}
opcache.php


<?php
if (!extension_loaded('Zend OPcache')) {
    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>';
    require 'data-sample.php';
}
class OpCacheDataModel
{
    private $_configuration;
    private $_status;
    private $_d3Scripts = array();
    public function __construct()
    {
        $this->_configuration = opcache_get_configuration();
        $this->_status = opcache_get_status();
    }
    public function getPageTitle()
    {
        return 'PHP ' . phpversion() . " with OpCache {$this->_configuration['version']['version']}";
    }
    public function getStatusDataRows()
    {
        $rows = array();
        foreach ($this->_status as $key => $value) {
            if ($key === 'scripts') {
                continue;
            }
            if (is_array($value)) {
                foreach ($value as $k => $v) {
                    if ($v === false) {
                        $value = 'false';
                    }
                    if ($v === true) {
                        $value = 'true';
                    }
                    if ($k === 'used_memory' || $k === 'free_memory' || $k === 'wasted_memory') {
                        $v = $this->_size_for_humans(
                            $v
                        );
                    }
                    if ($k === 'current_wasted_percentage' || $k === 'opcache_hit_rate') {
                        $v = number_format(
                                $v,
                                2
                            ) . '%';
                    }
                    if ($k === 'blacklist_miss_ratio') {
                        $v = number_format($v, 2) . '%';
                    }
                    if ($k === 'start_time' || $k === 'last_restart_time') {
                        $v = ($v ? date(DATE_RFC822, $v) : 'never');
                    }
                    $rows[] = "<tr><th>$k</th><td>$v</td></tr>\n";
                }
                continue;
            }
            if ($value === false) {
                $value = 'false';
            }
            if ($value === true) {
                $value = 'true';
            }
            $rows[] = "<tr><th>$key</th><td>$value</td></tr>\n";
        }
        return implode("\n", $rows);
    }
    public function getConfigDataRows()
    {
        $rows = array();
        foreach ($this->_configuration['directives'] as $key => $value) {
            if ($value === false) {
                $value = 'false';
            }
            if ($value === true) {
                $value = 'true';
            }
            if ($key == 'opcache.memory_consumption') {
                $value = $this->_size_for_humans($value);
            }
            $rows[] = "<tr><th>$key</th><td>$value</td></tr>\n";
        }
        return implode("\n", $rows);
    }
    public function getScriptStatusRows()
    {
        foreach ($this->_status['scripts'] as $key => $data) {
            $dirs[dirname($key)][basename($key)] = $data;
            $this->_arrayPset($this->_d3Scripts, $key, array(
                'name' => basename($key),
                'size' => $data['memory_consumption'],
            ));
        }
        asort($dirs);
        $basename = '';
        while (true) {
            if (count($this->_d3Scripts) !=1) break;
            $basename .= DIRECTORY_SEPARATOR . key($this->_d3Scripts);
            $this->_d3Scripts = reset($this->_d3Scripts);
        }
        $this->_d3Scripts = $this->_processPartition($this->_d3Scripts, $basename);
        $id = 1;
        $rows = array();
        foreach ($dirs as $dir => $files) {
            $count = count($files);
            $file_plural = $count > 1 ? 's' : null;
            $m = 0;
            foreach ($files as $file => $data) {
                $m += $data["memory_consumption"];
            }
            $m = $this->_size_for_humans($m);
            if ($count > 1) {
                $rows[] = '<tr>';
                $rows[] = "<th class=\"clickable\" id=\"head-{$id}\" colspan=\"3\"  '#row-{$id}')\">{$dir} ({$count} file{$file_plural}, {$m})</th>";
                $rows[] = '</tr>';
            }
            foreach ($files as $file => $data) {
                $rows[] = "<tr id=\"row-{$id}\">";
                $rows[] = "<td>{$data["hits"]}</td>";
                $rows[] = "<td>" . $this->_size_for_humans($data["memory_consumption"]) . "</td>";
                $rows[] = $count > 1 ? "<td>{$file}</td>" : "<td>{$dir}/{$file}</td>";
                $rows[] = '</tr>';
            }
            ++$id;
        }
        return implode("\n", $rows);
    }
    public function getScriptStatusCount()
    {
        return count($this->_status["scripts"]);
    }
    public function getGraphDataSetJson()
    {
        $dataset = array();
        $dataset['memory'] = array(
            $this->_status['memory_usage']['used_memory'],
            $this->_status['memory_usage']['free_memory'],
            $this->_status['memory_usage']['wasted_memory'],
        );
        $dataset['keys'] = array(
            $this->_status['opcache_statistics']['num_cached_keys'],
            $this->_status['opcache_statistics']['max_cached_keys'] - $this->_status['opcache_statistics']['num_cached_keys'],
            0
        );
        $dataset['hits'] = array(
            $this->_status['opcache_statistics']['misses'],
            $this->_status['opcache_statistics']['hits'],
            0,
        );
        $dataset['restarts'] = array(
            $this->_status['opcache_statistics']['oom_restarts'],
            $this->_status['opcache_statistics']['manual_restarts'],
            $this->_status['opcache_statistics']['hash_restarts'],
        );
        return json_encode($dataset);
    }
    public function getHumanUsedMemory()
    {
        return $this->_size_for_humans($this->getUsedMemory());
    }
    public function getHumanFreeMemory()
    {
        return $this->_size_for_humans($this->getFreeMemory());
    }
    public function getHumanWastedMemory()
    {
        return $this->_size_for_humans($this->getWastedMemory());
    }
    public function getUsedMemory()
    {
        return $this->_status['memory_usage']['used_memory'];
    }
    public function getFreeMemory()
    {
        return $this->_status['memory_usage']['free_memory'];
    }
    public function getWastedMemory()
    {
        return $this->_status['memory_usage']['wasted_memory'];
    }
    public function getWastedMemoryPercentage()
    {
        return number_format($this->_status['memory_usage']['current_wasted_percentage'], 2);
    }
    public function getD3Scripts()
    {
        return $this->_d3Scripts;
    }
    private function _processPartition($value, $name = null)
    {
        if (array_key_exists('size', $value)) {
            return $value;
        }
        $array = array('name' => $name,'children' => array());
        foreach ($value as $k => $v) {
            $array['children'][] = $this->_processPartition($v, $k);
        }
        return $array;
    }
    private function _size_for_humans($bytes)
    {
        if ($bytes > 1048576) {
            return sprintf('%.2f&nbsp;MB', $bytes / 1048576);
        } else {
            if ($bytes > 1024) {
                return sprintf('%.2f&nbsp;kB', $bytes / 1024);
            } else {
                return sprintf('%d&nbsp;bytes', $bytes);
            }
        }
    }
    // Borrowed from Laravel
    private function _arrayPset(&$array, $key, $value)
    {
        if (is_null($key)) return $array = $value;
        $keys = explode(DIRECTORY_SEPARATOR, ltrim($key, DIRECTORY_SEPARATOR));
        while (count($keys) > 1) {
            $key = array_shift($keys);
            if ( ! isset($array[$key]) || ! is_array($array[$key])) {
                $array[$key] = array();
            }
            $array =& $array[$key];
        }
        $array[array_shift($keys)] = $value;
        return $array;
    }
}
$dataModel = new OpCacheDataModel();
?>
<!DOCTYPE html>
<meta charset="utf-8">
<html>
<head>
    <style>
        body {
            font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
            margin: 0;
            padding: 0;
        }
        #container {
            width: 1024px;
            margin: auto;
            position: relative;
        }
        h1 {
            padding: 10px 0;
        }
        table {
            border-collapse: collapse;
        }
        tbody tr:nth-child(even) {
            background-color: #eee;
        }
        p.capitalize {
            text-transform: capitalize;
        }
        .tabs {
            position: relative;
            float: left;
            width: 60%;
        }
        .tab {
            float: left;
        }
        .tab label {
            background: #eee;
            padding: 10px 12px;
            border: 1px solid #ccc;
            margin-left: -1px;
            position: relative;
            left: 1px;
        }
        .tab [type=radio] {
            display: none;
        }
        .tab th, .tab td {
            padding: 8px 12px;
        }
        .content {
            position: absolute;
            top: 28px;
            left: 0;
            background: white;
            border: 1px solid #ccc;
            height: 450px;
            width: 100%;
            overflow: auto;
        }
        .content table {
            width: 100%;
        }
        .content th, .tab:nth-child(3) td {
            text-align: left;
        }
        .content td {
            text-align: right;
        }
        .clickable {
            cursor: pointer;
        }
        [type=radio]:checked ~ label {
            background: white;
            border-bottom: 1px solid white;
            z-index: 2;
        }
        [type=radio]:checked ~ label ~ .content {
            z-index: 1;
        }
        #graph {
            float: right;
            width: 40%;
            position: relative;
        }
        #graph > form {
            position: absolute;
            right: 60px;
            top: -20px;
        }
        #graph > svg {
            position: absolute;
            top: 0;
            right: 0;
        }
        #stats {
            position: absolute;
            right: 125px;
            top: 145px;
        }
        #stats th, #stats td {
            padding: 6px 10px;
            font-size: 0.8em;
        }
        #partition {
            position: absolute;
            width: 100%;
            height: 100%;
            z-index: 10;
            top: 0;
            left: 0;
            background: #ddd;
            display: none;
        }
        #close-partition {
            display: none;
            position: absolute;
            z-index: 20;
            right: 15px;
            top: 15px;
            background: #f9373d;
            color: #fff;
            padding: 12px 15px;
        }
        #close-partition:hover {
            background: #D32F33;
            cursor: pointer;
        }
        #partition rect {
            stroke: #fff;
            fill: #aaa;
            fill-opacity: 1;
        }
        #partition rect.parent {
            cursor: pointer;
            fill: steelblue;
        }
        #partition text {
            pointer-events: none;
        }
        label {
            cursor: pointer;
        }
    </style>
    <script src="//cdnjs.cloudflare.com/ajax/libs/d3/3.0.1/d3.v3.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
    <script>
        var hidden = {};
        function toggleVisible(head, row) {
            if (!hidden[row]) {
                d3.selectAll(row).transition().style('display', 'none');
                hidden[row] = true;
                d3.select(head).transition().style('color', '#ccc');
            } else {
                d3.selectAll(row).transition().style('display');
                hidden[row] = false;
                d3.select(head).transition().style('color', '#000');
            }
        }
    </script>
    <title><?php echo $dataModel->getPageTitle(); ?></title>
</head>
<body>
    <div id="container">
        <h1><?php echo $dataModel->getPageTitle(); ?></h1>
        <div class="tabs">
            <div class="tab">
                <input type="radio" id="tab-status" name="tab-group-1" checked>
                <label for="tab-status">Status</label>
                <div class="content">
                    <table>
                        <?php echo $dataModel->getStatusDataRows(); ?>
                    </table>
                </div>
            </div>
            <div class="tab">
                <input type="radio" id="tab-config" name="tab-group-1">
                <label for="tab-config">Configuration</label>
                <div class="content">
                    <table>
                        <?php echo $dataModel->getConfigDataRows(); ?>
                    </table>
                </div>
            </div>
            <div class="tab">
                <input type="radio" id="tab-scripts" name="tab-group-1">
                <label for="tab-scripts">Scripts (<?php echo $dataModel->getScriptStatusCount(); ?>)</label>
                <div class="content">
                    <table style="font-size:0.8em;">
                        <tr>
                            <th width="10%">Hits</th>
                            <th width="20%">Memory</th>
                            <th width="70%">Path</th>
                        </tr>
                        <?php echo $dataModel->getScriptStatusRows(); ?>
                    </table>
                </div>
            </div>
            <div class="tab">
                <input type="radio" id="tab-visualise" name="tab-group-1">
                <label for="tab-visualise">Visualise Partition</label>
                <div class="content"></div>
            </div>
        </div>
        <div id="graph">
            <form>
                <label><input type="radio" name="dataset" value="memory" checked> Memory</label>
                <label><input type="radio" name="dataset" value="keys"> Keys</label>
                <label><input type="radio" name="dataset" value="hits"> Hits</label>
                <label><input type="radio" name="dataset" value="restarts"> Restarts</label>
            </form>
            <div id="stats"></div>
        </div>
    </div>
    <div id="close-partition">&#10006; Close Visualisation</div>
    <div id="partition"></div>
    <script>
        var dataset = <?php echo $dataModel->getGraphDataSetJson(); ?>
        var width = 400,
            height = 400,
            radius = Math.min(width, height) / 2,
            colours = ['#B41F1F', '#1FB437', '#ff7f0e'];
        d3.scale.customColours = function() {
            return d3.scale.ordinal().range(colours);
        };
        var colour = d3.scale.customColours();
        var pie = d3.layout.pie().sort(null);
        var arc = d3.svg.arc().innerRadius(radius - 20).outerRadius(radius - 50);
        var svg = d3.select("#graph").append("svg")
                .attr("width", width)
                .attr("height", height)
                .append("g")
                .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
        var path = svg.selectAll("path")
                .data(pie(dataset.memory))
                .enter().append("path")
                .attr("fill", function(d, i) { return colour(i); })
                .attr("d", arc)
                .each(function(d) { this._current = d; }); // store the initial values
        d3.selectAll("input").on("change", change);
        set_text("memory");
        function set_text(t) {
            if (t === "memory") {
                d3.select("#stats").html(
                    "<table><tr><th style='background:#B41F1F;'>Used</th><td><?php echo $dataModel->getHumanUsedMemory()?></td></tr>"+
                    "<tr><th style='background:#1FB437;'>Free</th><td><?php echo $dataModel->getHumanFreeMemory()?></td></tr>"+
                    "<tr><th style='background:#ff7f0e;' rowspan=\"2\">Wasted</th><td><?php echo $dataModel->getHumanWastedMemory()?></td></tr>"+
                    "<tr><td><?php echo $dataModel->getWastedMemoryPercentage()?>%</td></tr></table>"
                );
            } else if (t === "keys") {
                d3.select("#stats").html(
                    "<table><tr><th style='background:#B41F1F;'>Cached keys</th><td>"+dataset[t][0]+"</td></tr>"+
                    "<tr><th style='background:#1FB437;'>Free Keys</th><td>"+dataset[t][1]+"</td></tr></table>"
                );
            } else if (t === "hits") {
                d3.select("#stats").html(
                    "<table><tr><th style='background:#B41F1F;'>Misses</th><td>"+dataset[t][0]+"</td></tr>"+
                    "<tr><th style='background:#1FB437;'>Cache Hits</th><td>"+dataset[t][1]+"</td></tr></table>"
                );
            } else if (t === "restarts") {
                d3.select("#stats").html(
                    "<table><tr><th style='background:#B41F1F;'>Memory</th><td>"+dataset[t][0]+"</td></tr>"+
                        "<tr><th style='background:#1FB437;'>Manual</th><td>"+dataset[t][1]+"</td></tr>"+
                        "<tr><th style='background:#ff7f0e;'>Keys</th><td>"+dataset[t][2]+"</td></tr></table>"
                );
            }
        }
        function change() {
            if (typeof dataset[this.value] !== 'undefined') {
                path = path.data(pie(dataset[this.value])); // update the data
                path.transition().duration(750).attrTween("d", arcTween); // redraw the arcs
                set_text(this.value);
            }
        }
        function arcTween(a) {
            var i = d3.interpolate(this._current, a);
            this._current = i(0);
            return function(t) {
                return arc(i(t));
            };
        }
        function size_for_humans(bytes) {
            if (bytes > 1048576) {
                    return (bytes/1048576).toFixed(2) + ' MB';
            } else if (bytes > 1024) {
                    return (bytes/1024).toFixed(2) + ' KB';
            } else return bytes + ' bytes';
        }
        var w = window.innerWidth,
                h = window.innerHeight,
                x = d3.scale.linear().range([0, w]),
                y = d3.scale.linear().range([0, h]);
        var vis = d3.select("#partition")
                .style("width", w + "px")
                .style("height", h + "px")
                .append("svg:svg")
                .attr("width", w)
                .attr("height", h);
        var partition = d3.layout.partition()
                .value(function(d) { return d.size; });
        root = JSON.parse('<?php echo json_encode($dataModel->getD3Scripts()); ?>');
        var g = vis.selectAll("g")
                .data(partition.nodes(root))
                .enter().append("svg:g")
                .attr("transform", function(d) { return "translate(" + x(d.y) + "," + y(d.x) + ")"; })
                .on("click", click);
        var kx = w / root.dx,
                ky = h / 1;
        g.append("svg:rect")
                .attr("width", root.dy * kx)
                .attr("height", function(d) { return d.dx * ky; })
                .attr("class", function(d) { return d.children ? "parent" : "child"; });
        g.append("svg:text")
                .attr("transform", transform)
                .attr("dy", ".35em")
                .style("opacity", function(d) { return d.dx * ky > 12 ? 1 : 0; })
                .text(function(d) { return d.name; })
        d3.select(window)
                .on("click", function() { click(root); })
        function click(d) {
            if (!d.children) return;
            kx = (d.y ? w - 40 : w) / (1 - d.y);
            ky = h / d.dx;
            x.domain([d.y, 1]).range([d.y ? 40 : 0, w]);
            y.domain([d.x, d.x + d.dx]);
            var t = g.transition()
                    .duration(d3.event.altKey ? 7500 : 750)
                    .attr("transform", function(d) { return "translate(" + x(d.y) + "," + y(d.x) + ")"; });
            t.select("rect")
                    .attr("width", d.dy * kx)
                    .attr("height", function(d) { return d.dx * ky; });
            t.select("text")
                    .attr("transform", transform)
                    .style("opacity", function(d) { return d.dx * ky > 12 ? 1 : 0; });
            d3.event.stopPropagation();
        }
        function transform(d) {
            return "translate(8," + d.dx * ky / 2 + ")";
        }
        $(document).ready(function() {
            function handleVisualisationToggle(close) {
                $('#partition, #close-partition').fadeToggle();
                // Is the visualisation being closed? If so show the status tab again
                if (close) {
                    $('#tab-visualise').removeAttr('checked');
                    $('#tab-status').trigger('click');
                }
            }
            $('label[for="tab-visualise"], #close-partition').on('click', function() {
                handleVisualisationToggle(($(this).attr('id') === 'close-partition'));
            });
            $(document).keyup(function(e) {
                if (e.keyCode == 27) handleVisualisationToggle(true);
            });
        });
    </script>
</body>
</html>

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-17846-1-1.html 上篇帖子: php 出现空格,换行原因 下篇帖子: phpMyAdmin:无法在发生错误时创建会话,请检查 PHP 或网站服... ubuntu
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表