開發者常想在除錯時取得變數的「名稱」(而非值)。網路上流傳一段利用 $GLOBALS 遍歷比對值的函數,但存在嚴重邏輯缺陷。
<?php
function getVarName(&$src) {
$save = $src;
$allvar = $GLOBALS;
foreach ($allvar as $k => $v) {
// ❌ 使用 == 鬆散比較,導致型別轉換錯誤
if ($src == $v) {
$src = 'change'; // 修改參考值
if ($src == $GLOBALS[$k]) { // 檢查全域變數是否同步變更
$src = $save; // 還原
return $k;
}
}
}
}
?>
<?php $test2 = "hello"; $countNum = 0; echo getVarName($test2); // 預期 "test2",實際輸出 "countNum" ?>
迴圈遍歷到 $countNum = 0 時:
$src == $v → "hello" == 000 == 0 為 true,誤判為同一變數"countNum"===<?php
function getVarName(&$src) {
$save = $src;
$allvar = $GLOBALS;
foreach ($allvar as $k => $v) {
// ✅ 使用 === 嚴格比較(型別與值皆同)
if ($src === $v) {
$src = 'change';
if ($src === $GLOBALS[$k]) {
$src = $save;
return $k;
}
}
}
return false; // 找不到時明確返回
}
?>
上述修正仍有邊界問題(如多個變數同值、參考關係複雜)。生產環境建議:
error_log(json_encode(['var' => $test2, 'value' => $test2]));debug_backtrace() 解析呼叫堆疊,但效能較差。💡 核心教訓:PHP 的
==涉及複雜型別轉換規則,除非極度確定型別一致,永遠優先使用===。此原則同樣適用於!=vs!==、switch語句(預設用鬆散比較)等場景。