Linux 通過 /proc 虛擬文件系統暴露內核數據,讀取並解析以下文件可獲取系統核心指標:
/proc/cpuinfo:CPU 型號、核心數、緩存大小/proc/meminfo:內存總量、可用、Swap 信息/proc/loadavg:1/5/15 分鐘負載/proc/uptime:系統啟動至今秒數<?php
/**
* Linux 系統信息採集器
* 僅在 Linux 環境下有效,需 PHP 有權限讀取 /proc 文件
*/
class LinuxSysInfo {
public static function get(): ?array {
if (PHP_OS_FAMILY !== 'Linux') {
return null;
}
$info = [];
// CPU 信息
$info['cpu'] = self::parseCpuInfo();
// 內存信息
$info['memory'] = self::parseMemInfo();
// 負載
$info['load'] = self::parseLoadAvg();
// 運行時間
$info['uptime'] = self::parseUptime();
return $info;
}
private static function parseCpuInfo(): array {
$content = @file_get_contents('/proc/cpuinfo');
if (!$content) return ['error' => '無法讀取 /proc/cpuinfo'];
$cpu = ['cores' => 0, 'model' => '', 'cache' => ''];
$lines = explode("\n", $content);
$models = [];
$caches = [];
foreach ($lines as $line) {
if (str_starts_with($line, 'processor')) {
$cpu['cores']++;
} elseif (str_starts_with($line, 'model name') && !$cpu['model']) {
$cpu['model'] = trim(explode(':', $line)[1] ?? '');
} elseif (str_starts_with($line, 'cache size') && !$cpu['cache']) {
$cpu['cache'] = trim(explode(':', $line)[1] ?? '');
}
}
// 多核心可能型號不同,收集所有
if (preg_match_all('/model name\s+:\s(.+)/', $content, $m)) {
$cpu['models'] = array_unique($m[1]);
}
if (preg_match_all('/cache size\s+:\s(.+)/', $content, $m)) {
$cpu['caches'] = array_unique($m[1]);
}
return $cpu;
}
private static function parseMemInfo(): array {
$content = @file_get_contents('/proc/meminfo');
if (!$content) return ['error' => '無法讀取 /proc/meminfo'];
$mem = ['total' => 0, 'free' => 0, 'available' => 0, 'used' => 0, 'percent' => 0];
$swap = ['total' => 0, 'free' => 0, 'used' => 0, 'percent' => 0];
$patterns = [
'MemTotal' => 'total',
'MemFree' => 'free',
'MemAvailable' => 'available',
'SwapTotal' => 'swap_total',
'SwapFree' => 'swap_free',
];
foreach ($patterns as $key => $field) {
if (preg_match("/{$key}:\\s+(\\d+)/", $content, $m)) {
$$field = (int)$m[1]; // kB
}
}
$mem['total'] = round($total / 1024, 2); // MB
$mem['free'] = round($free / 1024, 2);
$mem['available'] = round(($available ?? $free) / 1024, 2);
$mem['used'] = $mem['total'] - $mem['available'];
$mem['percent'] = $mem['total'] > 0 ? round($mem['used'] / $mem['total'] * 100, 2) : 0;
$swap['total'] = round(($swap_total ?? 0) / 1024, 2);
$swap['free'] = round(($swap_free ?? 0) / 1024, 2);
$swap['used'] = $swap['total'] - $swap['free'];
$swap['percent'] = $swap['total'] > 0 ? round($swap['used'] / $swap['total'] * 100, 2) : 0;
return ['memory' => $mem, 'swap' => $swap];
}
private static function parseLoadAvg(): array {
$content = @file_get_contents('/proc/loadavg');
if (!$content) return ['error' => '無法讀取 /proc/loadavg'];
$parts = explode(' ', trim($content));
return [
'1min' => (float)$parts[0],
'5min' => (float)$parts[1],
'15min' => (float)$parts[2],
'running_processes' => (int)explode('/', $parts[3])[0],
'total_processes' => (int)explode('/', $parts[3])[1],
'last_pid' => (int)$parts[4],
];
}
private static function parseUptime(): array {
$content = @file_get_contents('/proc/uptime');
if (!$content) return ['error' => '無法讀取 /proc/uptime'];
$seconds = (float)explode(' ', $content)[0];
$days = floor($seconds / 86400);
$hours = floor(($seconds % 86400) / 3600);
$minutes = floor(($seconds % 3600) / 60);
return [
'seconds' => $seconds,
'human' => sprintf('%d天 %d小時 %d分鐘', $days, $hours, $minutes),
'boot_time' => time() - $seconds,
];
}
}
// === 使用示例 ===
$data = LinuxSysInfo::get();
if ($data) {
echo '<pre>';
print_r($data);
echo '</pre>';
} else {
echo '非 Linux 環境或無權限讀取 /proc';
}
?>
Array
(
[cpu] => Array
(
[cores] => 8
[model] => Intel(R) Xeon(R) CPU E5-2680 v4 @ 2.40GHz
[cache] => 35840 KB
[models] => Array
(
[0] => Intel(R) Xeon(R) CPU E5-2680 v4 @ 2.40GHz
)
[caches] => Array
(
[0] => 35840 KB
)
)
[memory] => Array
(
[memory] => Array
(
[total] => 32768.00
[free] => 1234.56
[available] => 15678.90
[used] => 17089.10
[percent] => 52.15
)
[swap] => Array
(
[total] => 4096.00
[free] => 4096.00
[used] => 0.00
[percent] => 0.00
)
)
[load] => Array
(
[1min] => 0.52
[5min] => 0.48
[15min] => 0.45
[running_processes] => 3
[total_processes] => 215
[last_pid] => 12345
)
[uptime] => Array
(
[seconds] => 1234567.89
[human] => 14天 6小時 56分鐘
[boot_time] => 1700000000
)
)
<?php
// sysinfo_panel.php
$data = LinuxSysInfo::get();
?>
<!DOCTYPE html>
<html><head><title>系統監控</title>
<style>
body{font-family:monospace;padding:20px;background:#f5f5f5}
.card{background:white;padding:15px;margin-bottom:15px;border-radius:5px;box-shadow:0 1px 3px rgba(0,0,0,.1)}
.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:10px}
.metric{padding:10px;background:#f8f9fa;border-radius:3px}
.label{color:#666;font-size:.9em}
.value{font-size:1.2em;font-weight:bold;color:#333}
.warning{color:#dc3545}.ok{color:#28a745}
</style></head><body>
<h1>🖥 服務器系統信息</h1>
<div class="card">
<h2>CPU</h2>
<div class="grid">
<div class="metric"><div class="label">核心數</div><div class="value">= $data['cpu']['cores'] ?? 'N/A' ?></div></div>
<div class="metric"><div class="label">型號</div><div class="value">= htmlspecialchars($data['cpu']['model'] ?? 'N/A') ?></div></div>
<div class="metric"><div class="label">緩存</div><div class="value">= htmlspecialchars($data['cpu']['cache'] ?? 'N/A') ?></div></div>
</div>
</div>
<div class="card">
<h2>內存 & Swap</h2>
<div class="grid">
<div class="metric"><div class="label">總內存</div><div class="value">= $data['memory']['memory']['total'] ?? 0 ?> MB</div></div>
<div class="metric"><div class="label">已用</div><div class="value = $data['memory']['memory']['percent']>80?'warning':'ok' ?>">= $data['memory']['memory']['used'] ?? 0 ?> MB (= $data['memory']['memory']['percent'] ?? 0 ?>%)</div></div>
<div class="metric"><div class="label">可用</div><div class="value">= $data['memory']['memory']['available'] ?? 0 ?> MB</div></div>
<div class="metric"><div class="label">Swap 總計</div><div class="value">= $data['memory']['swap']['total'] ?? 0 ?> MB</div></div>
<div class="metric"><div class="label">Swap 已用</div><div class="value = $data['memory']['swap']['percent']>50?'warning':'ok' ?>">= $data['memory']['swap']['used'] ?? 0 ?> MB (= $data['memory']['swap']['percent'] ?? 0 ?>%)</div></div>
</div>
</div>
<div class="card">
<h2>負載 & 運行時間</h2>
<div class="grid">
<div class="metric"><div class="label">1 分鐘負載</div><div class="value = $data['load']['1min'] > $data['cpu']['cores'] ? 'warning' : 'ok' ?>">= $data['load']['1min'] ?? 'N/A' ?></div></div>
<div class="metric"><div class="label">5 分鐘負載</div><div class="value">= $data['load']['5min'] ?? 'N/A' ?></div></div>
<div class="metric"><div class="label">15 分鐘負載</div><div class="value">= $data['load']['15min'] ?? 'N/A' ?></div></div>
<div class="metric"><div class="label">運行時間</div><div class="value">= $data['uptime']['human'] ?? 'N/A' ?></div></div>
<div class="metric"><div class="label">進程數</div><div class="value">= $data['load']['running_processes'] ?? 0 ?> / = $data['load']['total_processes'] ?? 0 ?></div></div>
</div>
</div>
</body></html>
/proc/*(通常預設可讀)。/proc 反映宿主機信息,若需容器級指標請讀取 /sys/fs/cgroup/。