不能。PHP无法直接读取主板温度,因其运行在用户态且无内核权限,只能通过exec调用sensors等外部命令间接获取,但依赖宿主环境配置、权限、驱动支持等多重不可控因素,生产环境不推荐使用。

PHP 能不能直接读取主板温度
不能。PHP 是运行在用户态的脚本语言,没有内核权限,无法直接访问 /sys/class/hwmon 或 /proc/acpi/thermal_zone 这类硬件传感器路径。强行用 exec("sensors") 或 shell_exec("cat /sys/class/hwmon/hwmon0/temp1_input") 看似可行,但实际依赖宿主环境是否安装了硬件监控工具、是否有对应权限、路径是否固定——这些都不是 PHP 本身能保证的。
Linux 下获取主板温度的可靠前提
必须满足以下全部条件,exec() 方式才可能返回有效数据:
-
sensors命令已安装(来自lm-sensors包),且已执行过sensors-detect并加载对应内核模块(如coretemp、it87) - PHP 进程运行用户(如
www-data)对/sys/class/hwmon/下相关节点有读权限(默认常为 root 或root:hwmon,需加组或改 udev 规则) - 主板传感器被正确识别:运行
sensors应输出类似Package id 0: +42.0°C (high = +80.0°C, crit = +100.0°C) - 不依赖桌面环境(
psensor、ksensor等 GUI 工具无效)
PHP 中调用 sensors 的安全写法
避免直接拼接命令,防止 shell 注入;同时捕获错误并 fallback:
$output = [];
$returnCode = 0;
exec('sensors -u 2>/dev/null', $output, $returnCode);
if ($returnCode !== 0 || empty($output)) {
error_log('sensors command failed or returned no data');
return false;
}
// 解析 output 数组,找 'temp1_input' 对应行(不同芯片命名差异大)
foreach ($output as $line) {
if (preg_match('/^temp\d+_input:\s+(\d+)/', $line, $m)) {
$temp_mC = (int)$m[1]; // 单位是毫摄氏度
return round($temp_mC / 1000, 1); // → 42.3
}
}
注意:sensors -u 输出格式稳定,比默认格式更适合解析;temp1_input 不一定存在,有些主板用 temp2_input 或 fan1_input(其实是温度),得结合 sensors -A 实际输出判断。
立即学习“PHP免费学习笔记(深入)”;
为什么生产环境极少这么做
根本原因不是技术做不到,而是运维不可控:
- 每次系统升级、内核更新、主板更换都可能导致
/sys/class/hwmon/hwmon*/路径重排或传感器驱动失效 - Web 服务器通常以低权限用户运行,
chmod 644 /sys/class/hwmon/hwmon0/temp1_input是临时方案,重启即失效;持久化需写 udev rule,超出 PHP 职责范围 - 容器环境(Docker)默认不挂载
/sys/class/hwmon,即使挂载也受限于宿主机传感器支持程度 - 真正需要温度告警的场景(如机房服务器),应该由
collectd、telegraf或Zabbix agent统一采集,PHP 只查 API
如果真要从 Web 接口暴露温度,更稳妥的做法是:后台用 systemd service 定期跑一个 Python/Go 小程序把 sensors 结果写入 Redis 或本地 JSON 文件,PHP 只做读取——把硬件交互和业务逻辑彻底隔离。



















