首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 掃描區域網裝置:取得 IP、主機名與 MAC 位址完整實作

     編輯:PHP 綜合知識

核心原理

結合 PHP exec() 執行系統 arp -a 指令,解析輸出取得區域網裝置的 IP-MAC 對應表,再用 gethostbyaddr() 反解主機名。

完整可執行程式碼(CLI 模式)

= 224 && $lastOctet <= 239) continue; // 多播
        if ($type !== '動態' && $type !== 'dynamic') continue; // 只保留動態分配

        // 反解主機名(可能較慢,可選擇性啟用)
        $hostname = @gethostbyaddr($ip);
        if ($hostname === $ip) $hostname = '未知';

        echo "IP: $ip | MAC: $mac | 主機名: $hostname\n";
    }
}

Windows / Linux 跨平台相容性處理

function getArpCommand(): string
{
    return (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') ? 'arp -a' : 'arp -n';
}

function parseArpOutput(string $output): array
{
    $devices = [];
    $lines = explode("\n", $output);
    $currentIf = null;

    foreach ($lines as $line) {
        $line = trim($line);
        
        // 介面標題行
        if (preg_match('/(?:Interface|介面)\s*[:\s]\s*(\d+\.\d+\.\d+\.\d+)/i', $line, $m)) {
            $currentIf = $m[1];
            continue;
        }

        // 資料行:IP MAC TYPE
        // Windows:   192.168.1.50    00-11-22-33-44-55    動態
        // Linux:     192.168.1.50    ether   00:11:22:33:44:55   C   eth0
        if (preg_match('/(\d+\.\d+\.\d+\.\d+)\s+([\da-fA-F:-]{17})/i', $line, $m)) {
            $devices[] = [
                'ip' => $m[1],
                'mac' => str_replace('-', ':', $m[2]), // 統一用冒號
                'interface' => $currentIf,
            ];
        }
    }
    return $devices;
}

效能優化:非同步掃描大型網段

// 使用 pcntl_fork 或並行處理(需 CLI)
function scanSubnetParallel(string $subnet, int $concurrency = 50): Generator
{
    $pids = [];
    $results = [];
    
    for ($i = 1; $i <= 254; $i++) {
        $ip = "$subnet$i";
        
        // 限制並發數
        while (count($pids) >= $concurrency) {
            foreach ($pids as $pid => $fp) {
                if (feof($fp)) {
                    $results[$pid] = stream_get_contents($fp);
                    fclose($fp);
                    unset($pids[$pid]);
                }
            }
            usleep(10000);
        }

        // 非同步 ping + arp
        $cmd = "ping -n 1 -w 100 $ip >nul 2>&1 && arp -a $ip";
        $fp = popen($cmd, 'r');
        $pids[(int)$fp] = $fp;
    }

    // 收集剩餘
    foreach ($pids as $pid => $fp) {
        $results[$pid] = stream_get_contents($fp);
        fclose($fp);
    }

    foreach ($results as $output) {
        if (preg_match('/(\d+\.\d+\.\d+\.\d+)\s+([\da-fA-F-]{17})/i', $output, $m)) {
            yield ['ip' => $m[1], 'mac' => $m[2]];
        }
    }
}

權限與限制說明

限制說明解決方案
需 CLI 執行Web 環境通常禁用 exec()、無 arp 權限CLI 排程寫入資料庫,Web 讀取資料庫
arp 表不完整只含近期通訊過的裝置先發送廣播 ping 刷新鄰居表
防火牆阻擋ICMP/ARP 可能被封鎖需網管配合開放
主機名解析慢gethostbyaddr() 會發送 DNS/NetBIOS 查詢非同步解析、快取結果、或僅顯示 IP/MAC

安全替代方案:SNMP / Nmap

// 使用 php-snmp 擴充套件(需裝置支援 SNMP)
$session = new SNMP(SNMP::VERSION_2C, '192.168.1.1', 'public');
$interfaces = $session->walk('IF-MIB::ifDescr');

// 或呼叫 nmap(需安裝)
exec('nmap -sn 192.168.1.0/24 -oG -', $output);
// 解析 Grepable Output 格式
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved