如何在PDOStatement :: bindValue()中定义变量类型?

时间:2011-09-06 22:06:38

标签: php sql pdo pdostatement bindvalue

PDOStatement::bindValue()方法提供了一种指定变量绑定类型的方法:

  

PDOStatement :: bindValue($ parameter,$ value [, $ data_type = PDO :: PARAM_STR ])

我想知道,指定数据类型的目的是什么,而当作为默认值(PARAM_STR)离开时,数据库最终会在使用之前将值转换为正确的类型?

例如,如果您对INTEGER字段进行了这些查询:

INSERT INTO table (integerField) VALUES (?) ;
SELECT * FROM table WHERE integerField = ?  ;

你在PHP中绑定一个整数,默认情况下PDO将它绑定为一个字符串,相当于:

INSERT INTO table (integerField) VALUES ("1") ;
SELECT * FROM table WHERE integerField = "1"  ;

这将完美无缺,因为SQL数据库(至少是MySQL,我真的不知道它在其他RDBMS上是如何工作的)知道如何在使用它之前将字符串转换回整数。

哪些用例会对绑定的类型参数与字符串产生影响?

3 个答案:

答案 0 :(得分:7)

我不是PDO专家,但我可以想到一些场景,其中data_type参数既有用又需要。

输出参数

定义输出或输入/输出参数时,必须提供预期输出参数的类型和长度。

参考:http://www.php.net/manual/en/pdo.prepared-statements.php

示例#4

$stmt = $dbh->prepare("CALL sp_returns_string(?)");
$stmt->bindParam(1, $return_value, PDO::PARAM_STR, 4000); 

示例#5

$stmt = $dbh->prepare("CALL sp_takes_string_returns_string(?)");
$value = 'hello';
$stmt->bindParam(1, $value, PDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT, 4000); 

没有隐式投射的DBM

在这个问题的另一个答案中解释......

当参数未绑定到可投射数据时

即使具有施法能力的数据库也无法始终正确地投射变量。

参考:Reasons to strongly type parameters in PDO?

$limit = 1;

$dbh->prepare("SELECT * FROM items LIMIT :limit");
$dbh->bindParam(":limit", $limit, PDO::PARAM_STR); 
// Will throw "You have an error in your SQL syntax..."

答案 1 :(得分:3)

这主要是为了与需要正确输入的数据库进行交互。例如,如果在MySQL中启用严格模式,则在类型不匹配时会出现错误(查询失败)而不是警告。

默认情况下,MySQL会尽力正确转换数据。但是如果你曾经在日期字段中看到过0000-00-00,那很可能是mysql尝试将字符串转换为日期并失败的结果。在严格模式下,查询将失败,而不是尝试转换和使用结果。

答案 2 :(得分:1)

PDOStatement :: bindValue()的数据类型参数并不是非常有用。基本上:

  • 如果您告诉它PDO :: PARAM_STR,它会将您的值转换为字符串。
  • 如果告诉它PDO :: PARAM_INT并传递一个布尔值,它会将其转换为长整数。
  • 如果您告诉它PDO :: PARAM_BOOL并且您传递了一个long,它会将其转换为布尔值。

似乎没有其他东西被转换。请参阅here以快速查看源代码并获得更好的解释。也许最重要的是,如果您传递的数据类型与您传递的数据类型不匹配,PDO不会抛出异常或产生错误。