PDO查询绑定字符串而不是整数返回结果

时间:2017-03-31 10:46:59

标签: php mysql pdo

我有一个带有自动增量ID的表,当我偶然发现一个问题时,PDO或mysql似乎在一个数组中将字符串转换为整数时只测试了几个场景。有谁知道为什么?

如果我的查询如下:

$check = $db->prepare("SELECT * FROM tbl_test WHERE id=:id");
$check->execute(array(':id'=>1));

它检索1条记录 - 一切正常,但如果查询使用字符串设计或错误如下:

$check = $db->prepare("SELECT * FROM tbl_test WHERE id=:id");
$check->execute(array(':id'=>'1 OR id > 0'));

它仍会检索id = 1的记录。

肯定找不到任何东西?我很欣赏我永远不应该允许第二种情况发生,但为什么PDO / mysql将字符串转换为整数呢?它是如何做到的?

4 个答案:

答案 0 :(得分:3)

无论好坏,这就是MySQL的行为方式:

mysql> SELECT CASE
    -> WHEN 123='123 pink elephants' THEN 'Equal'
    -> ELSE 'Different' END
    -> AS 'How are they?';
+---------------+
| How are they? |
+---------------+
| Equal         |
+---------------+
1 row in set, 1 warning (0.00 sec)

但是,正如您所看到的,它会触发警告:

mysql> SHOW WARNINGS;
+---------+------+--------------------------------------------------------+
| Level   | Code | Message                                                |
+---------+------+--------------------------------------------------------+
| Warning | 1292 | Truncated incorrect DOUBLE value: '123 pink elephants' |
+---------+------+--------------------------------------------------------+
1 row in set (0.00 sec)

答案 1 :(得分:3)

这是一个MySQL错误/在字符串到整数转换中的疏忽。它给出了一个不正确的整数字面值,而不是引发错误,而只是发出警告。

mysql> select '1'+0;
+-------+
| '1'+0 |
+-------+
|     1 |
+-------+
1 row in set (0,00 sec)

mysql> select '1 hello world'+0;
+-------------------+
| '1 hello world'+0 |
+-------------------+
|                 1 |
+-------------------+
1 row in set, 1 warning (0,00 sec)

mysql> show warnings;
+---------+------+---------------------------------------------------+
| Level   | Code | Message                                           |
+---------+------+---------------------------------------------------+
| Warning | 1292 | Truncated incorrect DOUBLE value: '1 hello world' |
+---------+------+---------------------------------------------------+
1 row in set (0,00 sec)

答案 2 :(得分:0)

这是因为execute创建了类似:SELECT * FROM tbl_test WHERE id='1 OR id > 0'

的东西
$check = $db->prepare("SELECT * FROM tbl_test WHERE id=:id OR id>:id2");
$check->execute(array(':id'=>'1', ':id2' => 0));

或只是

$check = $db->prepare("SELECT * FROM tbl_test WHERE id>:id");
$check->execute(array(':id'=>'0'));

答案 3 :(得分:0)

使用预准备语句和占位符,数据库知道期望一个适合列类型的值。我希望它会看到您的数字ID列并转换为'1或id> 0'到数字 - 所以你得到1。