Introdução
O Opcache é um recurso do PHP para cachear o byte-code do código interpretado de um script PHP. Para ajudar a debugar o uso do Opcache, o PHP oferece a função opcache_get_status. Neste artigo vou compartilhar um script para visualizar o debug do retorno dessa função de forma amigável.
<?php
$status = opcache_get_status(true);
$mb = 1024 * 1024;
switch ($_GET['action'] ?? null) {
case 'invalidate_file':
opcache_invalidate($_GET['file'], true);
header(sprintf('Location: %s?%s', $_SERVER['PHP_SELF'], http_build_query(['sort' => $_GET['sort'] ?? 'full_path'])));
exit(0);
break;
case 'reset_all':
opcache_reset();
header(sprintf('Location: %s?%s', $_SERVER['PHP_SELF'], http_build_query(['sort' => $_GET['sort'] ?? 'full_path'])));
exit(0);
break;
}
$sortOptions = [
'full_path',
'hits',
'memory_consumption',
'last_used_timestamp',
'timestamp',
];
$sort = in_array($_GET['sort'] ?? null, $sortOptions) ? $_GET['sort'] : 'full_path';
usort($status['scripts'], fn($a, $b) => $a[$sort] <=> $b[$sort]);
?><!DOCTYPE html>
<head>
<title>Opcache Debug</title>
</head>
<body>
<div style="display: grid; grid-gap: 20px; grid-template-columns: auto auto; max-width: 1200px; margin: 10px auto;">
<div>
<table border>
<caption>php.ini</caption>
<tr><th>Config</th><th>Raw</th><th>Value</th></tr>
<?php foreach (opcache_get_configuration()['directives'] as $k => $v): ?>
<?php
printf(
'<tr><th>%s</th><td>%s<td>%s</td></tr>',
preg_replace('/^(opcache\.)/u', '<span style="color: #AAA;">\1</span>', $k),
var_export(ini_get($k), true),
var_export($v, true),
);
?>
<?php endforeach ?>
</table>
</div>
<div>
<table border>
<caption>Debug</caption>
<tr><th colspan="2">Opcache</th></tr>
<?php
printf(
'<tr><th>enabled</th><td>%s</td></tr><tr><th>full</th><td>%s</td></tr><tr><th>restart pending</th><td>%s</td></tr><tr><th>restart in progress</th><td>%s</td></tr>',
var_export($status['opcache_enabled'], true),
var_export($status['cache_full'], true),
var_export($status['restart_pending'], true),
var_export($status['restart_in_progress'], true),
);
?>
<tr><th colspan="2">Memory</th></tr>
<?php
printf(
'<tr><td align="center" colspan="2"><progress value="%d" max="%d">%0.2f%%</progress> (%0.2f%%)</td></tr>',
$status['memory_usage']['used_memory'],
$status['memory_usage']['used_memory'] + $status['memory_usage']['free_memory'],
$status['memory_usage']['used_memory'] * 100 / ($status['memory_usage']['used_memory'] + $status['memory_usage']['free_memory']),
$status['memory_usage']['used_memory'] * 100 / ($status['memory_usage']['used_memory'] + $status['memory_usage']['free_memory']),
);
printf(
'<tr><th>used</th><td>%0.2fMB</td></tr><tr><th>free</th><td>%0.2fMB</td></tr><tr><th>wasted</th><td>%0.2fMB (%0.2f%%)</td></tr>',
$status['memory_usage']['used_memory'] / $mb,
$status['memory_usage']['free_memory'] / $mb,
$status['memory_usage']['wasted_memory'] / $mb,
$status['memory_usage']['current_wasted_percentage'],
);
?>
<tr><th colspan="2">String</th></tr>
<?php
printf(
'<tr><th>buffer</th><td>%0.2fMB</td></tr><tr><th>used</th><td>%0.2fMB</td></tr><tr><th>free</th><td>%0.2fMB</td></tr><tr><th>total</th><td>%d</td></tr>',
$status['interned_strings_usage']['buffer_size'] / $mb,
$status['interned_strings_usage']['used_memory'] / $mb,
$status['interned_strings_usage']['free_memory'] / $mb,
$status['interned_strings_usage']['number_of_strings'],
);
?>
<tr><th colspan="2">Stats</th></tr>
<?php
foreach ($status['opcache_statistics'] as $k => $v) {
$fk = strtr($k, ['_' => ' ']);
if (is_float($v)) {
printf('<tr><th>%s</th><td>%0.2f</td></tr>', $fk, var_export($v, true));
} elseif (preg_match('/_time$/', $k) && is_int($v)) {
printf('<tr><th>%s</th><td>%s</td></tr>', $fk, date('c', $v));
} elseif (is_int($v)) {
printf('<tr><th>%s</th><td>%d</td></tr>', $fk, $v);
} else {
printf('<tr><th>%s</th><td>%s</td></tr>', $fk, var_export($v, true));
}
}
?>
</table>
</div>
<div style="grid-column-start: 1; grid-column-end: 3;">
<table border style="width: 100%">
<caption>Scripts</caption>
<?php
printf(
'<tr><th><a href="%s?%s">File</a></th><th><a href="%s?%s">hits</a></th><th><a href="%s?%s">mem. cons.</a></th><th><a href="%s?%s">last used</a></th><th><a href="%s?%s">created</a></th><th>options</th></tr>',
$_SERVER['PHP_SELF'],
http_build_query(['sort' => 'full_path']),
$_SERVER['PHP_SELF'],
http_build_query(['sort' => 'hits']),
$_SERVER['PHP_SELF'],
http_build_query(['sort' => 'memory_consumption']),
$_SERVER['PHP_SELF'],
http_build_query(['sort' => 'last_used_timestamp']),
$_SERVER['PHP_SELF'],
http_build_query(['sort' => 'timestamp']),
);
foreach ($status['scripts'] as $s) {
printf(
'<tr><td><small>%s</small></td><td>%d</td><td>%0.2fMB</td><td>%s</td><td>%s</td><td><a href="%s?%s">invalidate</a></td></tr>',
$s['full_path'],
$s['hits'],
$s['memory_consumption'] / $mb,
date('c', $s['last_used_timestamp']),
$s['timestamp'] ? date('c', $s['timestamp']) : 'null',
$_SERVER['PHP_SELF'],
http_build_query(['action' => 'invalidate_file', 'file' => $s['full_path'], 'sort' => $sort]),
);
}
?>
</table>
<?php
printf(
'<p>Global options: <a href="%s?%s">reset all cache</a></p>',
$_SERVER['PHP_SELF'],
http_build_query(['action' => 'reset_all', 'sort' => $sort]),
);
?>
</div>
</div>
</body>
</html>
1 comentário
Muito interessante
Postar um comentário
Nota: fique a vontade para expressar o que achou deste artigo ou do blog.
Dica: para acompanhar as respostas, acesse com uma conta do Google e marque a opção "Notifique-me".
Atenção: o blogger não permite inclusão de tags nos comentários, por isso, use algum site externo para postar seu código com dúvidas e deixe o link aqui. Exemplo: pastebin.com