首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 獲取 Linux 系統信息:CPU、內存、負載、運行時間完整解析

     編輯:PHP 相關知識

核心原理

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
        )
)

Web 面板展示版

<?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"></div></div>
        <div class="metric"><div class="label">型號</div><div class="value"></div></div>
        <div class="metric"><div class="label">緩存</div><div class="value"></div></div>
    </div>
</div>

<div class="card">
    <h2>內存 & Swap</h2>
    <div class="grid">
        <div class="metric"><div class="label">總內存</div><div class="value"> MB</div></div>
        <div class="metric"><div class="label">已用</div><div class="value 80?'warning':'ok' ?>"> MB (%)</div></div>
        <div class="metric"><div class="label">可用</div><div class="value"> MB</div></div>
        <div class="metric"><div class="label">Swap 總計</div><div class="value"> MB</div></div>
        <div class="metric"><div class="label">Swap 已用</div><div class="value 50?'warning':'ok' ?>"> MB (%)</div></div>
    </div>
</div>

<div class="card">
    <h2>負載 & 運行時間</h2>
    <div class="grid">
        <div class="metric"><div class="label">1 分鐘負載</div><div class="value  $data['cpu']['cores'] ? 'warning' : 'ok' ?>"></div></div>
        <div class="metric"><div class="label">5 分鐘負載</div><div class="value"></div></div>
        <div class="metric"><div class="label">15 分鐘負載</div><div class="value"></div></div>
        <div class="metric"><div class="label">運行時間</div><div class="value"></div></div>
        <div class="metric"><div class="label">進程數</div><div class="value"> / </div></div>
    </div>
</div>
</body></html>

權限與部署注意

  1. PHP 進程需有權限讀取 /proc/*(通常預設可讀)。
  2. 容器環境(Docker/K8s)中 /proc 反映宿主機信息,若需容器級指標請讀取 /sys/fs/cgroup/。
  3. 高併發頁面建議緩存結果 5-10 秒,避免頻繁讀取文件系統。
  4. 生產環境推薦使用 Prometheus + Node Exporter + Grafana 進行專業監控。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved