PDO :: PARAM_INT在bindParam中很重要?

时间:2013-11-03 09:07:13

标签: php mysql pdo

添加PDO::PARAM_INTPDO::PARAM_STR在Mysql查询中有什么意义吗?

$sql  = 'SELECT TagId FROM tagthread WHERE ThreadId = :ThreadId';

$stmt = $this->db->prepare($sql);
$stmt->bindParam(':ThreadId', $threadid, PDO::PARAM_INT);

$stmt->execute();

3 个答案:

答案 0 :(得分:21)

是的,请使用它。

我做了一些测试(使用PDO :: ATTR_EMULATE_PREPARES false),我发现值周围的引号会有所不同。

当您使用PARAM_INT绑定整数值时,查询中将不会有引号(带有PARAM_INT的字符串值具有引号)。如果将整数值与PDO::PARAM_STR绑定,则会有引号,而mysql必须转换为整数。

示例:

$stmt->bindParam(':ThreadId', $threadid, PDO::PARAM_INT);
$threadid = 123;
// SELECT TagId FROM tagthread WHERE ThreadId = 123
$threadid = '123test';
// SELECT TagId FROM tagthread WHERE ThreadId = '123test'
// mysql will cast 123test to 123

编辑:

我进一步测试并阅读了该主题。结论:Implicit casting is dangerous and can lead to unexpected results.详细了解here。始终使用PDO::PARAM_STR的另一个缺点是性能。详细了解效果Disadvantages of quoting integers in a Mysql query?

因此,如果您的列的类型为[TINY|SMALL|MEDIUM|BIG]INT,请使用PARAM_INT。如果PHP中的变量类型不是整数,则它是LIMIT子句而不是强制转换为整数。

答案 1 :(得分:1)

编辑:取决于! 查看您的常识评论如下。

如果值是整数,则应将其视为整数。 使用尽可能多的数据类型。

如果您未将PDO :: ATTR_EMULATE_PREPARES的属性设置为false,则会出现令人讨厌的错误。

坚实的例子:

$stmt = $dbh->prepare("SELECT * FROM table123 WHERE raw_field = :field LIMIT 1 OFFSET :offset;");
$stmt->bindParam(':field',  $field);
$stmt->bindParam(':offset', $offset);

if ($map_stmt->execute())
{
    $data = stmt->fetch(PDO::FETCH_ASSOC);
}
else
{
    echo 'Error :';
    echo '<pre>';
    print_r($map_stmt->errorInfo());
    print_r($map_stmt->debugDumpParams());
    echo '</pre>';
}

将返回一个令人讨厌的错误,其中包含:

  

错误代码:1064您的SQL语法出错;检查   手册,对应右边的MySQL服务器版本   要在&#39; 0&#39;&#39;&#39;&#39;&#39;&#39;&#39;在第1行

     

查询:SELECT * FROM table123 WHERE raw_field =&#39; home&#39; LIMIT 1 OFFSET&#39; 0&#39;

无用你将它视为一个整数,它会删除字符串(例如:&#39;&#39;)。

$stmt->bindParam(':offset', $offset, PDO::PARAM_INT);

简而言之:

你选择!是否严格数据..

答案 2 :(得分:-3)

我无法告诉PDO支持的所有驱动程序,但对于mysql,大部分时间都不能使用PDO::PARAM_INT

因此,使用大量bindParam调用来膨胀代码是没有意义的。通常,只需将变量直接发送到execute()

$sql  = 'SELECT TagId FROM tagthread WHERE ThreadId = ?';
$stmt = $this->db->prepare($sql);
$stmt->execute([$threadid]);

这里你的$threadid变量将被默认绑定为一个字符串,但是mysql将它与存储在数据库中的整数值进行比较不会有任何问题。 实际上,每个人都这样做,从来没有任何问题。

通过将仿真模式切换为OFF,可以很容易地解决LIMIT子句中字符串类型bindnig的问题。

请注意PDO::PARAM_INT doesn't cast your value。意味着如果您尝试使用此模式绑定字符串类型值,它将被绑定为字符串,即使您明确将类型设置为PDO::PARAM_INT。此模式实际上仅适用于整数值。

有些边缘情况可能需要显式绑定整数:

  • 特殊的列类型,如BIGINTBOOLEAN,需要绑定精确类型的操作数(请注意,为了将BIGINT值与PDO :: PARAM_INT绑定,您需要基于mysqlnd的安装)。
  • 一些DBA声称具有非平凡查询计划的复杂查询可能会受到错误操作数类型的影响。虽然没有人提供可验证的例子

松散打字所有其他问题都很常见,mysql和PDO绑定都没有任何特殊效果。

另外,为了避免可能出现的问题,您应该为数据选择正确的列类型。说,对于大整数,您应该使用BIGINT,而对于任何类似价格的数据,它必须使用是DECIMAL。并且没有一个问题可供比较。