PHP无法直接读取PCIe链路速度等级,只能通过file_get_contents()读取/sys/bus/pci/devices/XXXX:XX:XX.X/current_link_speed获取内核记录的当前协商速率(如8.0 GT/s),该值非最大支持速度且不实时更新。

PHP 本身无法直接读取 PCIe 链路速度等级
PHP 是运行在用户态的脚本语言,没有访问硬件寄存器、PCIe 配置空间或内核设备状态的权限。所谓“Gen3/Gen4”是物理链路协商结果,由 PCIe 控制器固件和内核驱动在启动时完成,并暴露为只读系统信息——PHP 只能间接读取这些已有输出,不能主动探测或监控链路。
/sys/bus/pci/devices/ 下的 current_link_speed 是最可靠来源
Linux 内核会把每个 PCIe 设备当前协商的速度等级(如 8.0 GT/s 对应 Gen3,16.0 GT/s 对应 Gen4)写入 /sys/bus/pci/devices/XXXX:XX:XX.X/current_link_speed。PHP 可用 file_get_contents() 读取该路径,但必须满足:
- Web 服务器进程(如 www-data)有读取
/sys/下对应路径的权限(通常默认可读) - 目标设备存在且已枚举(热插拔设备可能路径未生成)
- 路径中的 PCI 地址需事先知道,可通过
lspci -m或遍历/sys/bus/pci/devices/获取
示例:读取显卡链路速度
echo file_get_contents('/sys/bus/pci/devices/0000:01:00.0/current_link_speed');
输出可能是 8.0 GT/s,注意它不含单位缩写以外的空格,不等于 PCIe 3.0 这类字符串。
立即学习“PHP免费学习笔记(深入)”;
不要尝试用 exec() 调用 lspci 解析速度字段
lspci -vv 输出里确实有 LnkCap(能力)和 LnkSta(状态),但实际解析极不可靠:
-
lspci输出格式随版本变化,LnkSta:行中速度字段位置不固定 - 不同厂商对字段命名不一致(有的写
Speed 8GT/s,有的写Current Speed: 8.0GT/s) - 需要 root 权限才能看到完整
-vv输出,web 进程通常无权执行 - 调用外部命令开销大,且易被 SELinux / systemd 等安全策略拦截
相比直接读 /sys/ 文件,exec('lspci -vv') 是绕远路+埋雷。
current_link_speed 不代表最大支持速度,也不反映实时波动
这个值是内核在链路训练完成后记录的当前协商速率,但它:
- 不是设备最大能力(要看
max_link_speed,但该字段不一定存在) - 不会随链路降速(如因过热触发 L0s/L1 电源管理)而动态更新——它只在重训练后才变
- 某些老内核或虚拟化环境(如 KVM 直通未启用 ACS)可能根本不暴露该文件
如果你真需要监控链路是否降级,得配合 ethtool -S(网卡)、nvidia-smi(NVIDIA GPU)等专用工具轮询,PHP 只适合做一次性的状态快照,别当监控代理用。



















