如何在 PDOStatement::bindValue() 中定义变量类型?
Posted
技术标签:
【中文标题】如何在 PDOStatement::bindValue() 中定义变量类型?【英文标题】:How define the variable type in PDOStatement::bindValue()? 【发布时间】:2011-11-11 16:58:00 【问题描述】: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 上工作)知道如何在使用之前将字符串转换回整数。
在哪些用例中绑定类型参数和字符串会有所不同?
【问题讨论】:
***.com/questions/833510/…的可能重复 【参考方案1】:我不是 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..."
【讨论】:
仅这最后一个例子就让打字变得有意义!非常完整的解释,谢谢。【参考方案2】:这主要用于与需要正确输入的数据库交互。例如,如果您在 MySQL 中启用严格模式,当类型不匹配时,您将收到错误(查询失败)而不是警告。
默认情况下,MySQL 会尽力正确转换数据。但是,如果您曾经在日期字段中看到 0000-00-00,那很可能是 mysql 尝试将字符串转换为日期并失败的结果。在严格模式下,查询将失败,而不是尝试转换并使用任何结果。
【讨论】:
以前没听说过严格模式,有意思!【参考方案3】:PDOStatement::bindValue() 的数据类型参数并不是非常有用。本质上:
如果您告诉它 PDO::PARAM_STR,它会将您的值转换为字符串。 如果您告诉它 PDO::PARAM_INT 并传递一个布尔值,它会将其转换为长整数。 如果你告诉它 PDO::PARAM_BOOL 并且你传递了很长的值,它会将它转换为布尔值。似乎没有其他任何东西被转换。请参阅here 快速查看源代码和更好的解释。也许最重要的是,如果您传递的数据类型与您传递的数据类型不匹配,PDO 不会抛出异常或产生错误。
【讨论】:
抱歉,您可以从上面的答案中看到,此信息“本质上是错误的”。 @andho:此信息并非“本质上错误”。正如您在the answer to this question 中看到的(我在我的答案中也链接到了它),实际源代码 说这正是bindValue()
的工作原理。如果你想和源代码争论,那也没关系。
PDOStatement::bindValue() 的数据类型参数很有用,如果mysql在严格模式下运行,确实是必要的。
@andho:默认情况下不启用严格模式,所以是的,当为 PDO 的特定驱动程序之一设置了一个非默认设置时,这可能很有用。正如我在回答中指出的那样,对于您的边缘案例不适用的其他 99% 的用户,该设置并不是很有用。以上是关于如何在 PDOStatement::bindValue() 中定义变量类型?的主要内容,如果未能解决你的问题,请参考以下文章
如何在异步任务中调用意图?或者如何在 onPostExecute 中开始新的活动?