server/app/Utils/DiskInfoHelper.php

129 lines
3.6 KiB
PHP

<?php
namespace App\Utils;
class DiskInfoHelper
{
/**
* 获取所有磁盘信息
*/
public static function getAllDisks(): array
{
if (PHP_OS_FAMILY === 'Windows') {
return self::getWindowsDisks();
}
return self::getLinuxDisks();
}
/**
* Linux 系统:通过 df -T 获取磁盘信息
*/
protected static function getLinuxDisks(): array
{
$output = [];
@exec('df -T -B1 2>/dev/null', $output);
$disks = [];
$ignoreFs = ['tmpfs', 'devtmpfs', 'overlay', 'squashfs', 'proc', 'sysfs', 'cgroup'];
foreach ($output as $line) {
if (str_starts_with($line, 'Filesystem') || empty(trim($line))) {
continue;
}
[$filesystem, $type, $size, $used, $avail, $usePercent, $mount] = preg_split('/\s+/', $line);
if (in_array($type, $ignoreFs)) {
continue; // 过滤掉虚拟文件系统
}
$size = (int)$size;
$used = (int)$used;
$avail = (int)$avail;
$usePercent = rtrim($usePercent, '%');
$disks[] = [
'path' => $mount,
'filesystem' => $filesystem,
'type' => $type,
'total' => self::formatBytes($size),
'used' => self::formatBytes($used),
'available' => self::formatBytes($avail),
'used_percent' => (float)$usePercent . '%',
];
}
return $disks;
}
/**
* Windows 系统:通过 wmic 获取磁盘信息
*/
protected static function getWindowsDisks(): array
{
$output = [];
@exec('wmic logicaldisk get Caption,FileSystem,Size,FreeSpace,Description /format:list', $output);
$disks = [];
$current = [];
foreach ($output as $line) {
$line = trim($line);
if ($line === '') {
if (!empty($current)) {
$disks[] = self::formatWindowsDisk($current);
$current = [];
}
continue;
}
[$key, $value] = array_map('trim', explode('=', $line, 2) + [null, null]);
if ($key) {
$current[$key] = $value;
}
}
if (!empty($current)) {
$disks[] = self::formatWindowsDisk($current);
}
return $disks;
}
/**
* 格式化 Windows 磁盘数据
*/
protected static function formatWindowsDisk(array $data): array
{
$size = isset($data['Size']) ? (int)$data['Size'] : 0;
$free = isset($data['FreeSpace']) ? (int)$data['FreeSpace'] : 0;
$used = $size - $free;
$usedPercent = $size > 0 ? round($used / $size * 100, 2) : 0;
return [
'path' => $data['Caption'] ?? '',
'filesystem' => $data['FileSystem'] ?? '',
'type' => $data['Description'] ?? '',
'total' => self::formatBytes($size),
'used' => self::formatBytes($used),
'available' => self::formatBytes($free),
'used_percent' => $usedPercent . "%",
];
}
/**
* 格式化字节为易读形式
*/
protected static function formatBytes(int $bytes): string
{
if ($bytes <= 0) {
return '0 B';
}
$units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];
$i = (int)floor(log($bytes, 1024));
return sprintf('%.2f %s', $bytes / pow(1024, $i), $units[$i]);
}
}