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

PHP 獲取 MAC 地址的真相:只能拿伺服器端,無法直接取得客戶端

     編輯:PHP 相關知識

核心結論

PHP 執行在伺服器端,無法直接獲取客戶端(瀏覽器用戶)的 MAC 地址。 任何聲稱能用 PHP/JS 直接拿到訪客 MAC 的方案,要么是獲取伺服器自身網卡 MAC,要么需要客戶端安裝 ActiveX/簽名 Applet/瀏覽器擴展等高權限組件,現代瀏覽器已全面封殺。

程式碼分析:這其實是獲取「伺服器」網卡 MAC

<?php
class GetMacAddr {
  private $return_array = [];
  private $mac_addr = '';

  public function __construct($os_type = null) {
    $os_type = $os_type ?? PHP_OS;
    switch (strtolower($os_type)) {
      case 'linux':
      case 'freebsd':
      case 'unix':
      case 'solaris':
      case 'aix':
        $this->forLinux();
        break;
      default: // Windows
        $this->forWindows();
    }
    $this->parseMac();
  }

  private function forWindows() {
    @exec("ipconfig /all", $this->return_array);
    if (!$this->return_array) {
      $ipconfig = $_SERVER["WINDIR"] . "\\system32\\ipconfig.exe";
      if (is_file($ipconfig)) @exec($ipconfig . " /all", $this->return_array);
      else @exec($_SERVER["WINDIR"] . "\\system\\ipconfig.exe /all", $this->return_array);
    }
  }

  private function forLinux() {
    @exec("ifconfig -a", $this->return_array);
    // 現代 Linux 建議用: ip link show
  }

  private function parseMac() {
    foreach ($this->return_array as $line) {
      if (preg_match('/([0-9a-f]{2}[:-]){5}[0-9a-f]{2}/i', $line, $matches)) {
        $this->mac_addr = $matches[0];
        break;
      }
    }
  }

  public function getMac() {
    return $this->mac_addr;
  }
}

// 使用:只會返回 Web 伺服器本機的 MAC
$mac = new GetMacAddr();
echo "伺服器 MAC: " . $mac->getMac();

為什麼無法獲取客戶端 MAC?

層級說明
HTTP 協議不傳輸 MAC 地址,只在區域網路(第 2 層)傳輸,路由器轉發時丟棄
TCP/IP網際網路層級僅有 IP 地址,MAC 只在本地網段解析 ARP
瀏覽器沙箱JS 無權訪問硬體資訊,navigator、screen 等 API 均不包含 MAC
隱私保護現代瀏覽器刻意隱藏硬體指紋,防止追蹤

常見誤區澄清

  • 「用 $_SERVER['REMOTE_ADDR'] 拿 MAC」:只能拿 IP
  • 「用 JavaScript ActiveXObject('WbemScripting.SWbemLocator')」:僅 IE 老版本支援,需用戶降低安全級別、允許 ActiveX,現代環境不可行
  • 「用 Flash/Java Applet」:已淘汰,瀏覽器不再支援
  • 「用 WebRTC」:可獲取本地 IP(含內網 IP),但無法獲取 MAC

合法的替代方案:設備識別與指紋

1. Canvas 指紋 + ClientJS

<script src="https://cdn.jsdelivr.net/npm/clientjs@0.2.1/client.min.js"></script>
<script>
const client = new ClientJS();
const fingerprint = client.getFingerprint(); // 唯一瀏覽器指紋
console.log(fingerprint); // 如: 8a7f3e2d1c9b4e5f...
</script>

2. 伺服器端生成 UUID + Cookie 儲存

<?php
function getDeviceId() {
  if (isset($_COOKIE['device_id'])) return $_COOKIE['device_id'];
  $id = bin2hex(random_bytes(16));
  setcookie('device_id', $id, time() + 365*86400, '/', '', true, true);
  return $id;
}
?>

3. 內網環境:ARP 表查詢(僅限同一網段)

<?php
// 僅在伺服器與客戶端同一區域網路有效
function getMacFromArp($ip) {
  $output = shell_exec("arp -n $ip");
  // 輸出範例: 192.168.1.100  ether  00:11:22:33:44:55  C  eth0
  if (preg_match('/([0-9a-f]{2}[:-]){5}[0-9a-f]{2}/i', $output, $m)) {
    return $m[0];
  }
  return null;
}
// 注意:跨路由器/NAT 後 ARP 表無客戶端記錄

4. 企業內網:802.1X / RADIUS / DHCP 租約綁定

網路層面由交換器/認證伺服器綁定 MAC-IP-用戶,應用層透過 API 查詢。

總結建議

  1. 放棄「直接獲取客戶端 MAC」的想法,技術上不可行且違反隱私規範
  2. 改用瀏覽器指紋或伺服器端發放唯一 Cookie/Token識別設備
  3. 內網管理場景,配合網路設備(交換器、DHCP、RADIUS)實現 MAC-IP-人綁定
  4. 若極度需要硬體資訊,開發原生客戶端(Electron、Tauri、桌面 App)並簽名分發
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved