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

PHP 陣列數字鍵名陷阱:整數溢位、型別轉換與最佳實踐

     編輯:PHP 相關知識

核心規則

  1. 鍵名若為純數字字串且在有號整數範圍內,PHP 自動轉為 int 型別
  2. 超出平台整數範圍 (32 位系統 ±21億、64 位系統 ±9×10¹⁸) 會轉為 float,導致精度遺失與鍵名衝突
  3. 超長數字字串 (超過 19-20 位) 直接歸零
  4. 直接使用變數作鍵名 (而非字面值) 會依變數實際型別決定

實測案例

<?php
// 1. 正常範圍:字串鍵與整數鍵等價
$arr['123456'] = 'a';
$arr[123456]   = 'b';
var_dump($arr); // 只剩一個元素,值為 'b' (後者覆蓋)

// 2. 超出 32 位整數 (假設 32 位環境)
$big = '2147483648'; // 2^31
$arr[$big] = 'x';
var_dump(array_keys($arr)); // 鍵名可能變成 float 2147483648.0 或負數

// 3. 超長數字字串 (20+ 位)
$huge = '12345678901234567890';
$arr[$huge] = 'y';
var_dump(array_keys($arr)); // 鍵名變成 0 !

// 4. 變數直接作鍵名
$val = 123456789012345; // PHP 解析為 float
$arr[$val] = 'z';       // 實際鍵名為 float
$arr["$val"] = 'w';     // 字串鍵名,不同鍵
var_dump(array_keys($arr)); // 兩個不同鍵

最佳實踐:統一轉字串

function arr_set(array &$arr, $key, $value) {
    $arr[(string)$key] = $value;
}

function arr_get(array $arr, $key, $default = null) {
    return $arr[(string)$key] ?? $default;
}

function arr_has(array $arr, $key) {
    return array_key_exists((string)$key, $arr);
}

// 使用
$data = [];
arr_set($data, 12345678901234567890, 'safe');
arr_set($data, 'user_123', 'also safe');
echo arr_get($data, 12345678901234567890); // 'safe'

JSON 編碼/解碼陷阱

$json = '{"12345678901234567890": "value"}';
$arr = json_decode($json, true);
var_dump(array_keys($arr)); // 鍵名保持字串 "12345678901234567890" ✓

// 但 json_decode($json, false) 物件屬性名也為字串
$obj = json_decode($json);
echo $obj->{'12345678901234567890'}; // 需用大括號語法存取

資料庫 ID 陷阱

MySQL BIGINT (64 位) 最大值 9,223,372,036,854,775,807 (19 位),在 32 位 PHP 環境下直接放入陣列鍵名會溢位。解決:查詢時 CAST(id AS CHAR) 或 PHP 端 (string)$row['id']。

總結速查表

情境鍵名型別風險建議
短數字 (≤19位)int低可直接用,注意字串/整數等價
長數字 (>19位)float/0高強制 (string)$key
資料庫 BIGINTint/float中查詢轉字串或 PHP 轉字串
JSON 解碼string無安全,但物件存取需大括號
使用者輸入 IDstring低保持字串,驗證格式後再用
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved