浏览代码

Added invalidation option for individual files.
Added function list with links to php.net manuals.
Added a couple hard-coded values to the settings array.
Moved some javascript around.

Andrew Collington 12 年之前
父节点
当前提交
8e941b1fe7
共有 2 个文件被更改,包括 106 次插入53 次删除
  1. 17 2
      README.md
  2. 89 51
      index.php

+ 17 - 2
README.md

@@ -1,4 +1,19 @@
-opcache-gui
-===========
+# opcache-gui
 
 
 A simple, responsive interface for Zend OPcache information showing the statistics, settings and cached files.
 A simple, responsive interface for Zend OPcache information showing the statistics, settings and cached files.
+
+### overview
+
+The overview will show you all the core information.  From here you'll be able to see what host and platform you're running on, what version of OPcache you're using, when it was last reset, the functions that are available, all the directives and all the statistics associated with the OPcache (number of hits, memory used, free and wasted memory, etc.)
+
+### file usage
+
+All the files currently in the cache are listed here with their associated statistics.  You can filter the results very easily to key in on the particular scripts you're looking for, and you can optionally set levels of the path to be hidden (handy if they all share a common root and you don't want that displayed).
+
+### reset cache
+
+There is an option to reset the whole cache and you can also optionally force individual files to become invalidated so they will be cached again.  (NB: *Apparently, some version of PHP may cause a segmentation fault when using opcache_invalidate, so there is a setting in the gui script if you want to turn off the invalidate links.*)
+
+# License
+
+MIT: http://acollington.mit-license.org/

+ 89 - 51
index.php

@@ -1,15 +1,27 @@
 <?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')) {
 if (!function_exists('opcache_get_status')) {
     die('The Zend OPcache extension does not appear to be installed');
     die('The Zend OPcache extension does not appear to be installed');
 }
 }
 
 
 $settings = array(
 $settings = array(
-    'compress_path_threshold' => 2
+    'compress_path_threshold' => 2,
+    'used_memory_percentage_high_threshold' => 80,
+    'used_memory_percentage_mid_threshold' => 60,
+    'allow_invalidate' => true
 );
 );
 
 
 
 
-$validPages = array('overview', 'files', 'reset');
+$validPages = array('overview', 'files', 'reset', 'invalidate');
 $page = (empty($_GET['page']) || !in_array($_GET['page'], $validPages)
 $page = (empty($_GET['page']) || !in_array($_GET['page'], $validPages)
     ? 'overview'
     ? 'overview'
     : strtolower($_GET['page'])
     : strtolower($_GET['page'])
@@ -18,10 +30,23 @@ $page = (empty($_GET['page']) || !in_array($_GET['page'], $validPages)
 if ($page == 'reset') {
 if ($page == 'reset') {
     opcache_reset();
     opcache_reset();
     header('Location: ?page=overview');
     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_config = opcache_get_configuration();
 $opcache_status = opcache_get_status();
 $opcache_status = opcache_get_status();
+$opcache_funcs  = get_extension_funcs('Zend OPcache');
 
 
 if (!empty($opcache_status['scripts'])) {
 if (!empty($opcache_status['scripts'])) {
     uasort($opcache_status['scripts'], function($a, $b) {
     uasort($opcache_status['scripts'], function($a, $b) {
@@ -74,9 +99,9 @@ $data = array_merge(
 );
 );
 
 
 $threshold = '';
 $threshold = '';
-if ($data['used_memory_percentage'] >= 80) {
+if ($data['used_memory_percentage'] >= $settings['used_memory_percentage_high_threshold']) {
     $threshold = ' high';
     $threshold = ' high';
-} elseif ($data['used_memory_percentage'] >= 60) {
+} elseif ($data['used_memory_percentage'] >= $settings['used_memory_percentage_mid_threshold']) {
     $threshold = ' mid';
     $threshold = ' mid';
 }
 }
 
 
@@ -130,10 +155,12 @@ $host = (function_exists('gethostname')
         table tr.odd { background-color: #EFFEFF; }
         table tr.odd { background-color: #EFFEFF; }
         table tr.even { background-color: #E0ECEF; }
         table tr.even { background-color: #E0ECEF; }
         table tr.highlight { background-color: #61C4DF; }
         table tr.highlight { background-color: #61C4DF; }
+        td.pathname p { margin-bottom: 0.25em; }
         .wsnw { white-space: nowrap; }
         .wsnw { white-space: nowrap; }
         .low{color:#000000;}
         .low{color:#000000;}
         .mid{color:#550000;}
         .mid{color:#550000;}
         .high{color:#FF0000;}
         .high{color:#FF0000;}
+        .invalid{color:#FF4545;}
         span.showmore span.button {
         span.showmore span.button {
             display: inline-block;
             display: inline-block;
             margin-right: 5px;
             margin-right: 5px;
@@ -177,46 +204,6 @@ $host = (function_exists('gethostname')
             #frmFilter{width:99% !important;}
             #frmFilter{width:99% !important;}
         }
         }
     </style>
     </style>
-    <script type="text/javascript">
-        $(function(){
-            <?php if ($page == 'overview'): ?>
-            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');
-                }
-            });
-            <?php endif; ?>
-            <?php if ($page == 'files'): ?>
-            $('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('«');
-                }
-            });
-            <?php endif; ?>
-        });
-    </script>
 </head>
 </head>
 
 
 <body>
 <body>
@@ -295,13 +282,49 @@ $host = (function_exists('gethostname')
                     <td><span title="<?php echo $d; ?>"><?php echo str_replace(array('opcache.', '_'), array('', ' '), $d); ?></span></td>
                     <td><span title="<?php echo $d; ?>"><?php echo str_replace(array('opcache.', '_'), array('', ' '), $d); ?></span></td>
                     <td><?php echo (is_bool($v)
                     <td><?php echo (is_bool($v)
                         ? ($v ? '<i>true</i>' : '<i>false</i>')
                         ? ($v ? '<i>true</i>' : '<i>false</i>')
-                        : $v); ?></td>
+                        : (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>
                 </tr>
                 <?php endforeach; ?>
                 <?php endforeach; ?>
             </table>
             </table>
             <br style="clear:both;" />
             <br style="clear:both;" />
         </div>
         </div>
     </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 endif; ?>
 
 
     <?php if ($page == 'files'): ?>
     <?php if ($page == 'files'): ?>
@@ -316,7 +339,7 @@ $host = (function_exists('gethostname')
         </tr>
         </tr>
         <?php rc(0); foreach ($opcache_status['scripts'] as $s): ?>
         <?php rc(0); foreach ($opcache_status['scripts'] as $s): ?>
         <tr class="<?php rc(); ?>">
         <tr class="<?php rc(); ?>">
-            <td class="pathname"><?php 
+            <td class="pathname"><p><?php 
                 $base  = basename($s['full_path']);
                 $base  = basename($s['full_path']);
                 $parts = array_filter(explode(DIRECTORY_SEPARATOR, dirname($s['full_path'])));
                 $parts = array_filter(explode(DIRECTORY_SEPARATOR, dirname($s['full_path'])));
                 if (!empty($settings['compress_path_threshold'])) {
                 if (!empty($settings['compress_path_threshold'])) {
@@ -331,13 +354,19 @@ $host = (function_exists('gethostname')
                 } else {
                 } else {
                     echo htmlentities($s['full_path'], ENT_COMPAT, 'UTF-8');
                     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>
             <td>
             <td>
                 <p>
                 <p>
                     hits: <?php echo $s['hits']; ?>, 
                     hits: <?php echo $s['hits']; ?>, 
                     memory: <?php echo memsize($s['memory_consumption']); ?><br />
                     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'); ?>
                     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>
                 </p>
             </td>
             </td>
         </tr>
         </tr>
@@ -346,6 +375,15 @@ $host = (function_exists('gethostname')
     </div>
     </div>
     <script type="text/javascript">
     <script type="text/javascript">
         $(function(){
         $(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) {
             $('.container table').bind('paint', function(event, params) {
                 var trs = $('tr:visible', $(this)).not(':first');
                 var trs = $('tr:visible', $(this)).not(':first');
                 trs.removeClass('odd even')
                 trs.removeClass('odd even')
@@ -358,11 +396,11 @@ $host = (function_exists('gethostname')
                 ));
                 ));
             });
             });
             $('#frmFilter').bind('keyup', function(event){
             $('#frmFilter').bind('keyup', function(event){
-                $('td.pathname').each(function(index){
-                    if (($(this).text().toLowerCase().indexOf($('#frmFilter').val().toLowerCase())) == -1) {
-                        $(this).parent('tr').hide();
+                $('td.pathname p').each(function(index){
+                    if ($(this).text().toLowerCase().indexOf($('#frmFilter').val().toLowerCase()) == -1) {
+                        $(this).closest('tr').hide();
                     } else {
                     } else {
-                        $(this).parent('tr').show();
+                        $(this).closest('tr').show();
                     }
                     }
                 });
                 });
                 $('.container table').trigger('paint');
                 $('.container table').trigger('paint');