当我的查询有效但试图保存 provider_id
时,我在数据库中得到了一个不同的数字。
字段的类型是INT
。它不起作用(不同的数字),除非我尝试将字段类型更改为 VARCHAR
/* prepare query */
$query = 'INSERT INTO `users`(`first_name`,
`last_name`,
`gender`,
`username`,
`profile_picture`,
`provider`,
`provider_id`,
`provider_username`,
`provider_profile`,
`last_login`,
`created_date`,
`ip_address`)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NOW(), NOW(), INET_ATON(?))';
/* Prepare an insert statement */
$stmt = $mysqli->prepare($query);
if($stmt){
$stmt->bind_param("ssssssisss", $user['first_name'],
$user['last_name'],
$user['gender'],
$user['username'],
$user['link'],
$user['provider'],
$user['id'],
$user['username'],
$user['link'],
$_SERVER['REMOTE_ADDR']);
如果我错了请纠正我,虽然保存为 INT
我得到奇怪的负数:
-502711531
最佳答案
核心问题是在隐式转换期间丢失范围。
当 i
用作 mysqli 绑定(bind)提示时,它有效地执行 (int)value
。在 32 位系统中, session ID 超过了 PHP 整数的最大大小并且溢出:(int)"100007810775829"-> -502711531
。
当使用s
时,mysqli 不进行这种转换,而是将值直接传递给MySQL(作为字符串)。在这种情况下,MySQL 静默存储 maximum value it can对于字段,对于 INT 列是 2147483647
。
因此,将 s
与 BIGINT 字段一起使用会“有效”,因为:
- mysqli 不会尝试将值强制转换为整数
- MySQL BIGINT可以存储[-263, 263-1]
但是,我建议改用 CHAR 类型。这是因为 session ID 应该被视为一个不透明的标识符,不是一个数字——没有数学运算适用于它。此外,简单地使用 CHAR 可能会避免将来进行静默隐式转换,例如在处理可能错误地将 BIGINT 转换为整数或浮点 PHP 值的驱动程序时,因此(像这个问题)导致范围或精度丢失。
关于php - MySQL 在保存 Facebook session ID 时存储不同的数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23327421/