使用整数值变量的PHP mySQL INSERT语句

使用整数值变量的PHP mySQL INSERT语句,php,mysql,Php,Mysql,我正在尝试将一个(简单的)CSV文件导入MySQL表 我可以很好地连接,我已经用一些虚拟数据测试了该语句,并验证了它正确地写入了表中。当我试图在语句中使用变量时,问题就出现了。例如: $sql = "INSERT into `link_titles` (`title_id`, `title`, `description`) VALUES ('$data[0]', '$data[1]', '$data[2]')"; $conn->exec($sql); 这将生成错误: 未捕获PDOExce

我正在尝试将一个(简单的)CSV文件导入MySQL表

我可以很好地连接,我已经用一些虚拟数据测试了该语句,并验证了它正确地写入了表中。当我试图在语句中使用变量时,问题就出现了。例如:

$sql = "INSERT into `link_titles` (`title_id`, `title`, `description`) VALUES ('$data[0]', '$data[1]', '$data[2]')";
$conn->exec($sql);
这将生成错误:

未捕获PDOException:SQLSTATE[HY000]:一般错误:1366不正确 第1行“title\u id”列的整数值:“5”

因此,我假设第一个变量有问题,并从第一个变量中删除了单引号(
$data[0]
):

但是,如果我手动输入整数“5”(正在读取的值),则该值有效

$sql = "INSERT into `link_titles` (`title_id`, `title`, `description`) VALUES (5, '$data[1]', '$data[2]')";
$conn->exec($sql);
我曾研究过将字符串转换为整数(PHP应该处理这个问题),但当我尝试这样做时,它会转换为0

echo (int)$data[0];   <------  Results in 0
结果如下表所示:

desc link_titles;
+-------------+------------------+------+-----+---------+----------------+
| Field       | Type             | Null | Key | Default | Extra          |
+-------------+------------------+------+-----+---------+----------------+
| id          | int(11)          | NO   | PRI | NULL    | auto_increment |
| title_id    | int(10) unsigned | NO   | MUL | NULL    |                |
| title       | varchar(120)     | YES  |     | NULL    |                |
| description | varchar(512)     | YES  |     | NULL    |                |
+-------------+------------------+------+-----+---------+----------------+
更新#2 根据@Ligemar提供的评论和答案,我修改了PHP代码,如下所示:

$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$sql = $conn->prepare("INSERT into link_titles (title_id, title, description)
                      VALUES (:tid, :title, :description)");

$sql->bindParam(':tid', $tid);
$sql->bindParam(':title', $title);
$sql->bindParam(':description', $description);

//while loop to parse CSV file excluded for brevity

$tid = $data[0];
$title = $data[1];
$description = $data[2];

$sql->execute();
和以前一样,我仍然会遇到同样的错误:

Uncaught PDOException: SQLSTATE[HY000]: General error: 1366 Incorrect integer value: '5' for column 'title_id' at row 1

我假设您是从PDO编写的,因为您使用的是
->exec
方法

请使用以下参数:

特别是如果您刚开始使用PHP,那么进行SQL注入将使您成为一名差劲的开发人员,并养成坏习惯。使用准备好的SQL语句是正确的方法,因为查询将不会受到注入攻击,您可以更轻松地更改DB后端,提交事务并进行更好的调试,还可以提供缓存和其他“服务器端”功能

试着这样做:

<?php

$sql = 'INSERT into `link_titles` (`title_id`, `title`, `description`) 
        VALUES (:first, :second, :somethingelse)';

$sth = $dbh->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
$result = $sth->execute(
    [
     ':first' => $data[0], 
     ':second' => $data[1], 
     ':somethingelse' => $data[2]
    ]
);

var_dump($result);
其var$data[0]不是整数
UTF-8字节顺序标记(BOM)
在经历了大量的研究之后,我发现了这个问题:文件开头的UTF-8字节顺序标记(BOM)。1

修复文件后,我能够运行代码,没有问题,成功导入了文件

file test-nobom.csv
test-nobom.csv: UTF-8 Unicode text, with very long lines, with CRLF, LF line terminators
从文件中删除BOM表 显然,Windows OSs(虽然这是在Excel for Mac中完成的)将这个伪造字符添加到这些文本文件的前面。我找到了很多方法来修复它

  • Windows GUI编辑器:()
  • 使用
    sed
    2:

    sed'1s/^\xEF\xBB\xBF/'foo withoutBOM.txt

  • 使用
    dos2unix
    命令3

  • 使用
    tail
    命令4

    tail-c+4 foo-withBOM.txt>foo-withoutBOM.txt


一,

二,

三,


4

好的,首先,您的查询容易受到Sql注入的攻击……但是,如果您想继续在该路径上运行,则需要连接该值,例如:
$Sql=“INSERT into link_titles(title_id,title,description)值(“..data[0]”,“$data[1]”,“$data[2]”)…如果你想把事情做好,你应该去准备好的语句,只是好奇,你有没有考虑过为此加载数据填充?@Hackerman-谢谢你提供的信息。正如您所知,这不是我为公众消费而做的事情……它只是将数据导入到一个表中,并在其中学习一些PHP。在输入问题后,我继续研究,并发现了这个问题。我试过了,得到了同样的结果。@Don'tPanic-是的。我考虑过它,但选择了PHP,这样我就可以获得更多的经验(我不是开发人员)。我可能会以这种方式结束,但我想学习如何解决此问题以备将来使用。请显示您的创建表状态。与我使用的
(int)$data[0]相同值显示为
0
(零)$data[0]是一个字符串。因为您没有将title_id数据库int(10)中的列更改为title_id varchar(),虽然这不是解决方案(这是一个BOM问题),所以我非常感谢编码技术建议,并且我已经使用此技术更改了代码。是的,PHP不是整数类型的最佳选择;-)祝ya@Allan好运,我很好奇mysql函数是否也能解决您的问题。通过mysql直接导入它们是我研究的原因——它也给了我一个整数错误(将PHP从等式中去掉)。
<?php

$sql = 'INSERT into `link_titles` (`title_id`, `title`, `description`) 
        VALUES (:first, :second, :somethingelse)';

$sth = $dbh->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
$result = $sth->execute(
    [
     ':first' => $data[0], 
     ':second' => $data[1], 
     ':somethingelse' => $data[2]
    ]
);

var_dump($result);
try this function ==> intval($data[0]);
$ file test.csv
test.csv: UTF-8 Unicode (with BOM) text, with very long lines, with CRLF, LF line terminators
file test-nobom.csv
test-nobom.csv: UTF-8 Unicode text, with very long lines, with CRLF, LF line terminators