短鏈接系統中,自增 ID 與 6 位字符雙向映射。當 ID 超過 2147483647 (2^31-1,32 位有符號整數最大值) 時,PHP 在 32 位系統或舊版本中會將其視為負數,導致映射錯亂:
ID: 2147483647 → ffffVQ → 2147483647 ✓ ID: 2147483648 → nnnnnu → -2147483648 ✗ (溢出為負) ID: 2147483649 → dnnnnu → -2147483647 ✗
PHP_INT_MAX 的整數會轉為浮點數,精度可能丟失;某些運算(如位運算、格式化)會按有符號 32 位截斷。$id = 2147483648; // 超過 2^31-1
// 核心代碼
$unsigned = (float) sprintf('%u', $id);
var_dump($unsigned); // float(2147483648)
%u 格式化為無符號十進制字符串,(float) 轉為浮點數保持精度(53 位尾數可精確表示 2^53 以內整數)。
$id = '2147483648'; // 以字符串傳入 $unsigned = bcadd($id, '0'); // 返回字符串 '2147483648' // 參與運算時用 bcadd/bcmul/bcdiv 等
$id = gmp_init('2147483648');
$unsigned = gmp_strval($id); // '2147483648'
// 運算:gmp_add, gmp_mul, gmp_div_q 等
function idToCode($id) {
$id = (float) sprintf('%u', $id); // 關鍵修正
$chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$code = '';
while ($id > 0) {
$code = $chars[bcmod($id, 62)] . $code;
$id = bcdiv($id, 62);
}
return str_pad($code, 6, '0', STR_PAD_LEFT);
}
function codeToId($code) {
$chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$id = '0';
for ($i = 0; $i < strlen($code); $i++) {
$id = bcadd(bcmul($id, 62), strpos($chars, $code[$i]));
}
return $id; // 返回字符串形式大整數
}
// 測試
$id = '2147483648';
$code = idToCode($id);
$back = codeToId($code);
echo "ID: $id → Code: $code → Back: $back\n"; // 完全一致
BIGINT UNSIGNED,PHP 端以字符串/BCMath/GMP 處理,避免整型溢出。