在 PHP 專案中,我們習慣在 DAO 層對寫入 MySQL 的資料進行預處理:對 varchar 型別執行 trim(),對 int 型別則使用 intval() 強制轉型。某天突然想到一個關鍵問題:PHP 的 intval() 回傳範圍,是否與 MySQL 的 INT 型別完全一致?
查閱官方文件後發現,兩者的取值範圍存在顯著差異:
intval(): 受作業系統位元數影響
INT(有號): 固定為 -2,147,483,648 ~ 2,147,483,647,與作業系統無關INT UNSIGNED(無號): 0 ~ 4,294,967,295BIGINT(有號): -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807BIGINT UNSIGNED(無號): 0 ~ 18,446,744,073,709,551,615以下程式碼在 64 位元環境下執行時,若 $data['user_id'] 超過 2147483647,寫入 MySQL INT 欄位會發生截斷或報錯:
public function insert($data) {
if (isset($data['content']) && !empty($data['content'])) {
$data_for_query['content'] = trim($data['content']);
} else {
return false;
}
if (isset($data['user_id']) && !empty($data['user_id'])) {
$data_for_query['user_id'] = intval($data['user_id']); // 危險!
} else {
return false;
}
// ... 後續 SQL 組裝與執行
}
不要盲目相信 intval()。應根據資料庫欄位型別,在 PHP 端進行範圍檢查與截斷:
INT:限制在 -2147483648 ~ 2147483647INT UNSIGNED:限制在 0 ~ 4294967295BIGINT:可直接使用 intval()(64 位元環境)建議封裝一個 safeIntval($val, $type = 'int') 函式,根據目標欄位型別自動處理邊界,避免資料寫入時發生不可預期的截斷或錯誤。