2147483647即使数据类型为VARCHAR,也会插入到DB字段中

时间:2014-05-15 10:47:36

标签: php mysql mysqli varchar

这是我们现在已经敲了近一个星期的事情。

发生了什么?

  • 在我们的应用程序中,我们有一个电话号码字段,它与数据类型为VARCHAR(25)的数据库字段有关。我们使用INT,BIGINT。

  • 在表单提交时,我们将数据存储如下。

    1. $_POST

    2. 使用filter_input(INPUT_POST, 'mobile', FILTER_SANITIZE_STRING);

    3. 清理数据
    4. 使用mysqli->prepare将数据插入数据库,其中bind-params也已正确设置。此字段设置为使用" s" (字符串)。

    5. 然后将数据存储到数据库中。

  • 现在我们正在调试问题时将所有这些值记录在单独的日志文件中。在查看日志文件时发现了最奇怪的事情。似乎数据在通过POST发送时正确出现,在卫生设施后仍然很好,在插入数据库后立即检索时仍然很好。但是当我们的前端应用程序提取相同的值以显示给用户端时,获取的数据为2147483647.

  • 这个问题不会发生在所有这样的插入中,它发生得非常随机,而且很少发生,但却让我们陷入了困境,我正在努力寻找解决方案。

  • 开发平台信息:PHP 5.3,MySQL 5.5.31

非常感谢任何帮助。

代码

以下是代码:

$Mobile = filter_input(INPUT_POST, 'mobile', FILTER_SANITIZE_STRING);

$stmt = $mysqli->prepare("INSERT INTO enquiry(idAdminUsers, isConverted, Firstname, Lastname , Residence , WorkCollege , Gender , Age , Occupation , Mobile , Email , Transport , FirstMile , LastMile , Commute , NoPublicTransport , Member , YesMember , PurposeMember , NoMember , Note, Date, FirstMileCost, FirstMileTime, LastMileCost, LastMileTime, landlineNumber) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,NOW(),?,?,?,?,?)");
    if ($stmt) {
        if ($stmt->bind_param('iisssssissssssssisssssssss', $idAdminUsers, $isConverted, $firstName, $lastName, $Residence, $WorkCollege, $Gender, $Age, $Occupation, $Mobile, $Email, $Transport, $FirstMile, $LastMile, $Commute, $NoPublicTransport, $Member, $YesMember, $PurposeMember, $NoMember, $Note, $FirstMileCost, $FirstMileTime, $LastMileCost, $LastMileTime, $landlineNumber)) {
$stmt->execute()' 

插入后立即执行检索

$stmt = $mysqli->prepare("SELECT idEnquiry , idAdminUsers , isConverted , Firstname , Lastname , Residence , WorkCollege , Gender , Age , Occupation , Mobile , Email , Transport , FirstMile , LastMile , Commute , NoPublicTransport , Member , YesMember , PurposeMember , NoMember , Note, Date, FirstMileCost, FirstMileTime, LastMileCost, LastMileTime, landlineNumber FROM enquiry WHERE idEnquiry = ?");
    if ($stmt) {
        if ($stmt->bind_param('i', $idEnquirySelect)) {
            if ($stmt->execute()) {

这会被记录,并显示数据已正确输入。但是,一旦我们去检查数据库,随机数据就不正确了。

以下是数据库表创建脚本:

CREATE TABLE IF NOT EXISTS `enquiry` (
  `idEnquiry` int(11) NOT NULL AUTO_INCREMENT,
  `Firstname` varchar(255) DEFAULT NULL,
  `Mobile` varchar(25) DEFAULT NULL,
  `Email` varchar(45) DEFAULT NULL,
  `Age` int(16) DEFAULT NULL,
  `idAdminUsers` int(11) DEFAULT NULL,
  `Member` tinyint(4) DEFAULT NULL,
  `isConverted` tinyint(4) DEFAULT NULL,
  `Note` text,
  `Residence` varchar(255) DEFAULT NULL,
  `WorkCollege` varchar(255) DEFAULT NULL,
  `Transport` varchar(31) DEFAULT NULL,
  `FirstMile` varchar(31) DEFAULT NULL,
  `LastMIle` varchar(31) DEFAULT NULL,
  `Gender` varchar(8) DEFAULT NULL,
  `Commute` text,
  `NoPublicTransport` varchar(64) DEFAULT NULL,
  `YesMember` varchar(255) DEFAULT NULL,
  `PurposeMember` varchar(128) DEFAULT NULL,
  `NoMember` varchar(128) DEFAULT NULL,
  `Occupation` varchar(64) DEFAULT NULL,
  `Lastname` varchar(255) DEFAULT NULL,
  `Date` date DEFAULT NULL,
  `FirstMileCost` varchar(45) DEFAULT NULL,
  `FirstMileTime` varchar(45) DEFAULT NULL,
  `LastMileCost` varchar(45) DEFAULT NULL,
  `LastMileTime` varchar(45) DEFAULT NULL,
  `landlineNumber` varchar(15) NOT NULL,
  PRIMARY KEY (`idEnquiry`),
  UNIQUE KEY `idenquiry_UNIQUE` (`idEnquiry`),
  UNIQUE KEY `Email_UNIQUE` (`Email`),
  KEY `idAdminUserFK_idx` (`idAdminUsers`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COMMENT='All the enquiry details are added to this table.' AUTO_INCREMENT=482 ;

2 个答案:

答案 0 :(得分:9)

分析

你在这里有两条主要线索。

第一条线索:2147483647

我们对2147483647了解多少?

来自维基百科(http://en.wikipedia.org/wiki/2147483647):

  

数字2,147,483,647也是计算中32位有符号整数的最大值。因此,它是在流行计算机上运行的许多编程语言中声明为int的变量的最大值。

我们怎样才能获得数据库创建的这个数字?

在几个方面,都与INT有关,但由于你的“Mobile”字段数据类型是VARCHAR而不是INT,正如你明确强调的那样,我们知道问题不在数据库本身。如果该字段是INT,我们可以继续探索数据库本身以寻找可能的问题。所以我们消除了这种可能性这给我们留下了可能的代码问题。

第二条线索:日志

  

这会被记录,并显示数据已正确输入。但是一旦我们去检查数据库,随机数据就不正确了。

每次选择查询在插入完成后第一次运行并被记录时 - 它显示(在日志中)输入的数据是正确的,然后当你检查数据库时 - 有时它是正确的,有时它是2147483647。

(通常)可疑

根据这些信息,可以安全地假设PHP正在将字符串转换为某个地方的整数,然后在已经正确插入之后将该值放入/更新到db中。

调试

有几种很好的方法可以调试它:

1)搜索是否有另一个UPDATE query将数据输入到Mobile字段并覆盖插入的正确数据。对“Mobile”这一术语的所有文件进行完整代码搜索可能是一个良好的开端。

2)在代码中搜索intval的任何出现,因为此函数(或其他类似的函数/方法)可以将字符串转换为2147483647:Converting a String to an Integer returns 2147483647

3)在MySQL数据库中搜索2147483647的任何其他事件,只是为了确定这是否是一个孤立的问题,或者是否有其他任何东西获得此值,并且可能通过某种查询或其他方法将此值复制到Mobile字段。

希望这有帮助。

答案 1 :(得分:1)

  

...插入后立即检索到它仍然很好   DB。   但是当我们的前端获取相同的值时   要显示给用户端的应用程序,获取的数据是   2147483647。

显示的数据是2147483647而不是提取的数据

因为如果是后者,那么这意味着正在改变数据库中的数据,您需要检查后端和/或属性修改表单(如果有的话)。

如果前者,我被引导相信,那么它可能是一种非常特殊且罕见的手机号码格式(可能包含空格?+前缀?破折号?其他?)被错误地传递,可能是部分(例如,未加前缀的部分)到intval()或类似的功能,要格式化显示。

验证数据库中是否有一个“错误”的数字仍未完整;如果是,只需按照控制器并查看路径,数字显示为2147483647。