在服务器运维和本地设备管理场景中,经常需要通过PHP脚本识别热插拔硬盘的实时状态,检测可移除存储设备的接入与断开情况。PHP本身没有原生的硬件检测函数,但可以结合系统命令调用和扩展模块实现相关功能。

不同系统环境下的实现思路
PHP检测可移除存储设备的核心逻辑是调用对应操作系统的存储管理命令,获取设备列表后解析状态信息。不同系统的命令和输出格式存在差异,需要分别处理。
Linux系统实现方案
Linux系统下可以通过lsblk命令获取所有块设备信息,其中可移除设备的RM字段值为1,热插拔硬盘通常也属于可移除设备范畴。我们可以通过PHP的exec函数执行命令并解析结果。
<?php
/**
* Linux系统下检测可移除存储设备(含热插拔硬盘)
* @return array 可移除设备列表
*/
function get_removable_devices_linux() {
$output = [];
// 执行lsblk命令,输出设备名、移除标记、挂载点、大小信息
exec('lsblk -o NAME,RM,SIZE,MOUNTPOINT -n -l', $output);
$removableDevices = [];
foreach ($output as $line) {
// 跳过空行
if (empty(trim($line))) {
continue;
}
// 解析每行内容,按空格分割(处理多个空格的情况)
$parts = preg_split('/s+/', trim($line));
if (count($parts) < 2) {
continue;
}
$deviceName = $parts[0];
$rmFlag = $parts[1]; // RM字段,1表示可移除
$size = $parts[2];
$mountPoint = isset($parts[3]) ? $parts[3] : '未挂载';
// 筛选可移除设备
if ($rmFlag == '1') {
$removableDevices[] = [
'device' => '/dev/' . $deviceName,
'size' => $size,
'mount_point' => $mountPoint,
'is_hotplug' => true // Linux下可移除块设备通常为热插拔设备
];
}
}
return $removableDevices;
}
// 调用示例
$devices = get_removable_devices_linux();
echo "Linux系统下检测到的可移除存储设备:n";
print_r($devices);
?>
Windows系统实现方案
Windows系统下可以通过wmic命令查询磁盘分区信息,结合Win32_Volume类的属性判断是否为可移除设备。可移除存储设备的DriveType通常为2,热插拔硬盘对应的分区也符合该特征。
<?php
/**
* Windows系统下检测可移除存储设备(含热插拔硬盘)
* @return array 可移除设备列表
*/
function get_removable_devices_windows() {
$output = [];
// 执行wmic命令获取卷信息,包含驱动器路径、类型、大小、可用空间
exec('wmic volume get DriveLetter,DriveType,Size,FreeSpace /value', $output);
$removableDevices = [];
$currentDevice = [];
foreach ($output as $line) {
$line = trim($line);
if (empty($line)) {
// 空行表示一个设备信息结束,判断是否为可移除设备
if (!empty($currentDevice) && isset($currentDevice['DriveType']) && $currentDevice['DriveType'] == '2') {
$removableDevices[] = [
'drive_letter' => $currentDevice['DriveLetter'] ?? '未知盘符',
'size' => isset($currentDevice['Size']) ? round($currentDevice['Size'] / 1024 / 1024 / 1024, 2) . 'GB' : '未知',
'free_space' => isset($currentDevice['FreeSpace']) ? round($currentDevice['FreeSpace'] / 1024 / 1024 / 1024, 2) . 'GB' : '未知',
'is_hotplug' => true
];
}
$currentDevice = [];
continue;
}
// 解析键值对
if (strpos($line, '=') !== false) {
list($key, $value) = explode('=', $line, 2);
$currentDevice[trim($key)] = trim($value);
}
}
return $removableDevices;
}
// 调用示例
$devices = get_removable_devices_windows();
echo "Windows系统下检测到的可移除存储设备:n";
print_r($devices);
?>
状态轮询与热插拔事件识别
要识别热插拔硬盘的实时状态变化,可以通过定时轮询的方式调用上述检测函数,对比前后两次的设备列表差异,判断设备是接入还是移出。
<?php
/**
* 轮询检测热插拔设备状态变化
* @param int $interval 轮询间隔(秒)
* @param int $times 轮询次数
*/
function monitor_hotplug_devices($interval = 2, $times = 10) {
$lastDevices = [];
// 根据系统选择对应的检测函数
$detectFunc = strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' ? 'get_removable_devices_windows' : 'get_removable_devices_linux';
for ($i = 0; $i < $times; $i++) {
$currentDevices = $detectFunc();
// 获取当前设备标识列表
$currentIds = array_column($currentDevices, 'device') ?: array_column($currentDevices, 'drive_letter');
$lastIds = array_column($lastDevices, 'device') ?: array_column($lastDevices, 'drive_letter');
// 检测新接入的设备
$added = array_diff($currentIds, $lastIds);
if (!empty($added)) {
echo "检测到设备接入:" . implode(',', $added) . "n";
}
// 检测移出的设备
$removed = array_diff($lastIds, $currentIds);
if (!empty($removed)) {
echo "检测到设备移出:" . implode(',', $removed) . "n";
}
$lastDevices = $currentDevices;
// 未到最后一次则等待间隔
if ($i < $times - 1) {
sleep($interval);
}
}
}
// 启动监控,每2秒检测一次,共检测10次
monitor_hotplug_devices(2, 10);
?>
注意事项
- 执行系统命令需要PHP有对应的执行权限,Linux下可能需要给web服务用户(如www-data)赋予执行
lsblk的权限。 - Windows下执行
wmic命令需要确保PHP运行环境可以调用系统wmic工具,部分精简版系统可能缺少该组件。 - 轮询间隔不要设置过短,避免占用过多系统资源,建议根据实际需求设置2-5秒的间隔。
- 检测到的设备信息仅为系统层面的识别结果,若需要更精准的热插拔硬盘判断,可以结合设备的硬件ID进一步过滤。
通过上述方法,就可以用PHP函数实现热插拔硬盘状态的识别和可移除存储设备的检测,满足设备管理相关的业务需求。开发者可以根据实际运行的操作系统选择对应的实现方案,也可以封装统一的接口兼容多系统环境。
PHP可移除存储设备热插拔硬盘disk_status修改时间:2026-07-12 11:36:15