php需通过读取/sys/class/net/iface/speed(单位mbps)判断网卡是否为10gbe或25gbe,值为10000或25000即确认;若不可用则fallback至lang=c ethtool iface解析speed行;禁用pcie带宽、驱动名等不可靠依据。

PHP 怎么判断网卡是不是 10GbE 或 25GbE
PHP 本身不直接识别网卡速率,它没能力读取物理网卡的协商速率(比如 ethtool eth0 显示的 Speed: 25000Mb/s)。你得靠调用系统命令、解析 /sys 接口,或查 ethtool 输出——PHP 只是执行者和解析器。
常见错误是直接用 exec("lspci | grep -i ethernet") 就以为能分清千兆还是万兆:PCIe 插槽带宽 ≠ 网卡实际链路速率,且虚拟化环境里根本看不到真实硬件。
- 优先走
/sys/class/net/<iface>/speed</iface>:这是内核暴露的当前链路协商速率(单位 Mbps),值为10000或25000才算可靠依据 - 若该文件不存在或报
Invalid argument(常见于未 link up 的接口、bond 成员、或某些 driver 不支持),再 fallback 到ethtool <iface></iface>解析Speed:行 - 别信
lshw -class network或lspci -vv里的 “Width” 或 “LnkCap”,那是 PCIe 通道能力,不是网络链路能力
用 PHP 读取 /sys/class/net/eth0/speed 最简健壮写法
这个路径最轻量、无依赖、权限要求低(只要 PHP 进程能读 sysfs),但要注意:它只在网卡已 up 且链路通时才有值;down 状态下会返回 0 或直接 failed to open stream。
示例逻辑:
function getLinkSpeed(string $iface): ?int
{
$path = "/sys/class/net/{$iface}/speed";
if (!is_readable($path)) {
return null;
}
$speed = trim(file_get_contents($path));
if ($speed === '' || !is_numeric($speed)) {
return null;
}
return (int)$speed;
}
// 返回 10000 → 10GbE,25000 → 25GbE,1000 → 千兆,null → 无法确定
var_dump(getLinkSpeed('enp1s0f0'));
- 必须检查
is_readable(),不能直接file_get_contents()—— 权限不足或接口名错误时会触发 warning - 返回
null比返回0更安全:0可能是真实速率(极罕见),也可能是读取失败,语义模糊 - 不要硬编码
eth0,生产环境网卡名多为enp0s31f6或ens1f0,建议先用scandir('/sys/class/net')过滤出非 lo、非 bond/vlan 的物理接口
ethtool 解析的坑:输出格式不一致、中文 locale、sudo 依赖
当 /sys/class/net/<iface>/speed</iface> 不可用时,ethtool 是第二选择,但它问题更多:不同版本输出字段名可能小写(speed)、带单位(25000 Mb/s)、甚至被本地化成中文(如 “速度:25000 Mb/s”)。
- 强制英文环境:
exec("LANG=C ethtool {$iface} 2>/dev/null", $out),否则正则匹配失效 - 匹配行要宽松:
preg_grep('/^\s*Speed:\s*(\d+)/i', $out),忽略大小写和空格,兼容Speed和speed - 避免
shell_exec()直接拼接变量——有 shell 注入风险;用escapeshellarg()包裹接口名 - 如果 PHP 运行在容器中且没装 ethtool,或进程没权限执行(尤其启用了 seccomp),会静默失败,务必加超时和 fallback
为什么不能只看 PCI 设备 ID 或驱动名
有人试图用 lspci -n -s $(lspci | grep Eth | head -1 | cut -d' ' -f1) 查 vendor:device ID,再查数据库对应速率——这完全不可靠。同一款芯片(如 Broadcom BCM57414)可配置成 10G/25G/50G/100G,实际跑多少取决于 SFP 模块、交换机端口、BIOS 设置。
-
modinfo tg3或modinfo ixgbe只说明驱动支持哪些速率,不代表当前启用 - 虚拟机里看到的
virtio_net或e1000驱动,根本无法反映宿主机物理网卡能力 - DPDK 应用绕过内核协议栈后,
/sys/class/net/<iface>/speed</iface>可能仍显示旧值,需以 DPDK 自己的 port info 为准(PHP 无法直接访问)
真正有意义的永远是当前链路协商结果,不是硬件规格、驱动能力或虚拟设备抽象。这点容易被忽略,尤其在混用裸金属、KVM、SR-IOV 的场景里——你以为检测到 25GbE,其实流量全走的是 1GbE 的管理口。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











