【问题标题】:MySQL stores a different number when saving Facebook Session IDMySQL 在保存 Facebook Session ID 时存储不同的数字
【发布时间】:2014-06-13 04:37:35
【问题描述】:

当我的查询有效但尝试保存 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

【问题讨论】:

  • 尝试使用intval($user['id']) 而不是只使用$user['id'] 并告诉我结果
  • 您尝试插入的实际 ID 值是多少?
  • 它是来自 facebook 用户会话 @user2864740 的 id
  • @jenny 那么,的价值是多少?将其包含在帖子中。
  • @jenny (2147483647) 是 MySQL INT 字段的最大大小。当使用i 时,转换发生在in PHP(实际上是(int)ID 并溢出),而s 它发生在in MySQL 中,它只是“被封顶” "但没有溢出。如果您在 MySQL 中使用 s 切换到 BIGINT,那么它应该可以工作。但是,为避免类似(意外)转换问题,请考虑使用 CHAR 字段。

标签: php mysql mysqli insert prepared-statement


【解决方案1】:

核心问题是隐式转换过程中丢失范围。

i 用作mysqli 绑定提示时,它有效地执行(int)value。在 32 位系统中,会话 ID 超过了 PHP 整数的最大大小并且溢出(int)"100007810775829" -> -502711531

当使用s 时,mysqli 不会进行此转换,而是将值直接传递给 MySQL(作为字符串)。在这种情况下,MySQL 为字段静默存储 maximum value it can,对于 INT 列,2147483647

因此,使用s with BIGINT 字段将“起作用”,因为:

  1. mysqli 不会尝试将值强制为整数
  2. MySQL BIGINT 可以存储 [-263, 263-1]

不过,我建议改用 CHAR 类型。这是因为会话 ID 应被视为 不透明标识符not 应被视为数字 - 没有数学运算适用于它。此外,简单地使用 CHAR 可能会避免将来的静默隐式转换,例如在处理可能错误地将 BIGINT 转换为整数或浮点 PHP 值的驱动程序时,因此(像这个问题一样)导致范围或精度丢失。

【讨论】:

  • 曾经遇到过这个问题。我还将数据类型从 int 更改为 bigint 并且有效。但不知道原因。很好解释。 +1。
  • @ParagTyagi Cool :) 这个问题有 mysqli 内部处理的额外乐趣。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-10-01
  • 2019-09-10
  • 2019-10-15
  • 1970-01-01
  • 2014-05-24
  • 1970-01-01
  • 2015-03-13
相关资源
最近更新 更多