| 操作 | 變數是否存在 | 記憶體釋放 | 陣列索引保留 | 適用場景 |
|---|---|---|---|---|
unset($var) | 否(isset() 回傳 false) | 立即釋放(參考計數歸零時) | 否(索引移除,鍵名消失) | 徹底移除變數、釋放大型資料結構記憶體 |
$var = null | 是(isset() 回傳 false,但 array_key_exists 為 true) | 值釋放,變數槽位保留 | 是(索引保留,值為 null) | 重置值、保留結構、避免「未定義變數」通知 |
<?php
// 陣列情境
$a = ['a' => 'A', 'b' => 'B'];
$b = ['a' => 'A', 'b' => 'B'];
$a['b'] = null; // 值設為 null,鍵 'b' 保留
unset($b['b']); // 鍵 'b' 連同值一起移除
echo "=== \$a ===\n";
var_dump($a); // ['a' => 'A', 'b' => null]
echo "isset(\$a['b']): " . (isset($a['b']) ? 'true' : 'false') . "\n"; // false
echo "array_key_exists('b', \$a): " . (array_key_exists('b', $a) ? 'true' : 'false') . "\n"; // true
echo "\n=== \$b ===\n";
var_dump($b); // ['a' => 'A']
echo "isset(\$b['b']): " . (isset($b['b']) ? 'true' : 'false') . "\n"; // false
echo "array_key_exists('b', \$b): " . (array_key_exists('b', $b) ? 'true' : 'false') . "\n"; // false
?>
<?php
class Demo { public $val = 1; }
$obj1 = new Demo();
$obj2 = $obj1; // 指派:複製參考(handle),指向同一物件
$obj3 = &$obj1; // 參考:別名,綁定同一變數槽位
$obj2 = null; // 斷開 $obj2 與物件的關聯,物件仍存活($obj1 仍持有)
var_dump($obj1); // object(Demo)#1 (1) { ["val"]=> int(1) }
$obj3 = null; // 透過參考設為 null,實際操作 $obj1 所在槽位,物件被銷毀
var_dump($obj1); // NULL
?&rt;
結論: unset() 移除變數綁定;$var = null 修改變數持有的值。對於物件,前者減少參考計數,後者可能觸發解構子(若計數歸零)。
unset($largeArray) 釋放記憶體,避免超過 memory_limit。unset() 斷開循環參考能更早回收。unset()。unset(): 語意明確「不再需要此變數」。$arr[$key] = null: 如表單驗證錯誤訊息陣列,預設所有欄位為 null。$var = null 後又 isset($var) 判斷: 永遠回傳 false,改用 array_key_exists 或 !== null。null 而非未定義,配合 ?? 運算子(PHP 7+)更優雅。理解 unset() 與 null 指派的本質差異,能寫出更精準的資源管理代碼,避免陣列索引錯位、記憶體洩漏等隱性 Bug。原則上:「要移除變數用 unset,要重置值用 null」。