You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP执行ping检测主机存活时目标不可达误判为在线的修复方案

PHP关键设备Ping监控误判修复方案

问题原因

原有检测逻辑仅通过匹配ping返回结果中的Received = 1字段判定设备在线,但Windows环境下ping收到网关返回的Destination host unreachable(目标主机不可达)报文时,统计段同样会出现该字段——此时收到的是路由/网关返回的ICMP错误包,并非目标设备的正常存活响应,因此导致离线设备被误判为在线。

修复逻辑

在原有成功匹配规则基础上,新增错误特征排除:只要返回结果包含目标不可达、请求超时两类错误标识,无论统计字段是否显示Received=1,均判定为离线。同时修复原有代码中strpos判断不严谨、计数逻辑冲突、命令参数未转义三个隐藏bug,将检测和渲染流程拆分,保证计数准确。

修复后完整代码

function CriticalSystem( &$SC, &$FC ){ // 引用传递在线、离线计数变量
    // 关键设备监控列表
    $systems = array( 
        array('ip' => '8.8.8.8', 'name' => 'Leased Line Connection (Virgin BT Failover)'),     
        array('ip' => '192.168.11.254', 'name' => 'Hostname'), 
        array('ip' => '192.168.11.205', 'name' => 'Hostname'),
        array('ip' => '192.168.11.200', 'name' => 'Hostname'),
        array('ip' => '192.168.11.201', 'name' => 'Hostname'),
        array('ip' => 'WIN-FHPBMBL2E24', 'name' => 'Hostname'),
        array('ip' => '192.168.11.1', 'name' => 'Hostname'),
        array('ip' => '192.168.11.2', 'name' => 'Hostname'),
        array('ip' => '192.168.11.3', 'name' => 'Hostname'),
        array('ip' => '192.168.11.4', 'name' => 'Hostname'),
        array('ip' => '192.168.11.7', 'name' => 'Hostname'),
        array('ip' => '192.168.11.13', 'name' => 'Hostname'),
        array('ip' => '192.168.11.71', 'name' => 'Hostname'),
        array('ip' => '192.168.11.69', 'name' => 'Hostname'),
        array('ip' => '192.168.11.100', 'name' => 'Hostname'),
        array('ip' => '192.168.11.5', 'name' => 'Hostname'),
        array('ip' => '192.168.11.6', 'name' => 'Hostname'),
        array('ip' => '192.168.11.11', 'name' => 'Hostname'),
        array('ip' => '192.168.11.12', 'name' => 'Hostname'),
        array('ip' => '192.168.11.9', 'name' => 'Hostname'),
        array('ip' => '192.168.11.14', 'name' => 'Hostname'),
        array('ip' => '192.168.11.8', 'name' => 'Hostname'),
        array('ip' => '192.168.11.10', 'name' => 'Hostname'),
        array('ip' => '192.168.11.210', 'name' => 'Hostname'),
        array('ip' => '192.168.11.211', 'name' => 'Hostname'),
        array('ip' => '192.168.11.243', 'name' => 'Hostname'),
        array('ip' => '192.168.11.249', 'name' => 'Hostname'),
        array('ip' => '192.168.11.250', 'name' => 'Hostname'),
        array('ip' => '192.168.11.251', 'name' => 'Hostname'),
        array('ip' => '192.168.11.252', 'name' => 'Hostname'),
        array('ip' => '192.168.11.248', 'name' => 'Hostname'),
        array('ip' => '192.168.11.247', 'name' => 'Hostname'),
        array('ip' => '192.168.11.253', 'name' => 'Hostname'),
        array('ip' => 'DESKTOP-AF7UN0J', 'name' => 'Hostname'),
        array('ip' => '192.168.11.244', 'name' => 'Hostname'),
    );

    // 匹配规则定义
    $successFlag = "Received = 1";
    $errorFlags = [
        "Destination host unreachable",
        "Request timed out"
    ];
    $detectResults = [];
    $SC = 0;
    $FC = 0;

    // 第一阶段:完成所有设备ping检测
    foreach ($systems as $device) {
        unset($pingResult);
        $status = "DOWN";
        $hasError = false;
        // 转义参数避免命令注入风险
        exec("ping -n 1 " . escapeshellarg($device['ip']), $pingResult);
        
        foreach($pingResult as $line) {
            // 先匹配错误标识,命中直接判定为离线
            foreach($errorFlags as $errText) {
                if (stripos($line, $errText) !== false) {
                    $hasError = true;
                    break 2;
                }
            }
            // 无错误前提下匹配成功标识
            if (strpos($line, $successFlag) !== false) {
                $status = "UP";
            }
        }

        // 命中错误规则强制覆盖为离线
        if ($hasError) {
            $status = "DOWN";
        }

        $detectResults[] = [
            'ip' => $device['ip'],
            'name' => $device['name'],
            'status' => $status
        ];
    }

    // 第二阶段:渲染表格并统计计数
    echo "<table border='0' class='table'>";
    foreach ($detectResults as $item) {
        if ($item['status'] == "UP") {
            $SC++;
            $statusHtml = "<img src='/Images/GTick.jpg'><span style='color:#FFFFFF'>". $SC ."</span>";
        } else {
            $FC++;
            $statusHtml = "<img src='/Images/RTick.jpg'><span style='color:#FFFFFF'>". $FC ."</span>";
        }

        echo "<tbody>
                 <tr>
                    <td>IP Address: {$item['ip']}</td>
                    <td VALIGN = Middle Align = Center>Unit Name: {$item['name']}</td>
                 </tr>
                 <tr>
                    <td>Status is: {$item['status']}</td>
                    <td VALIGN = Middle Align = Center>{$statusHtml}</td>
                  </tr>
             </tbody>
             ";
     }
    echo"</table>";
}

改动说明

  • 错误拦截逻辑:只要ping结果包含目标不可达、请求超时任意一种错误特征,直接判定为离线,从根源解决Received=1误判问题
  • 语法bug修复:将strpos的判断从== TRUE改为!== false严格匹配,避免字符串出现在行首位置0时出现判断失效
  • 安全加固:使用escapeshellarg转义传入ping命令的IP/主机名参数,避免特殊字符引发命令注入风险
  • 计数逻辑优化:拆分检测和渲染流程,所有设备检测完成后再遍历输出表格,在线/离线序号累加准确,不会出现原有代码最后强制覆盖$FC导致的计数错乱问题

内容的提问来源于stack exchange,提问作者James

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 18:54:22