PHP 執行在伺服器端,無法直接獲取客戶端(瀏覽器用戶)的 MAC 地址。 任何聲稱能用 PHP/JS 直接拿到訪客 MAC 的方案,要么是獲取伺服器自身網卡 MAC,要么需要客戶端安裝 ActiveX/簽名 Applet/瀏覽器擴展等高權限組件,現代瀏覽器已全面封殺。
<?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();
| 層級 | 說明 |
|---|---|
| HTTP 協議 | 不傳輸 MAC 地址,只在區域網路(第 2 層)傳輸,路由器轉發時丟棄 |
| TCP/IP | 網際網路層級僅有 IP 地址,MAC 只在本地網段解析 ARP |
| 瀏覽器沙箱 | JS 無權訪問硬體資訊,navigator、screen 等 API 均不包含 MAC |
| 隱私保護 | 現代瀏覽器刻意隱藏硬體指紋,防止追蹤 |
<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>
<?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;
}
?>
<?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 表無客戶端記錄
網路層面由交換器/認證伺服器綁定 MAC-IP-用戶,應用層透過 API 查詢。