无论指定或给定什么数据类型,bindParam都能正常工作


bindParam works correctly no matter what data type is specified or given

在向自己介绍pgSQL准备的语句时,我成功地返回了一些查询的结果。不过,我有几个问题。

给定以下查询:

$w_ft = "36"; 
$sth = $dbh->prepare("SELECT * FROM main_products_common_dimensions WHERE w_ft = :w_ft");
$sth->bindParam(':w_ft', $theId, PDO::PARAM_INT);
$sth->execute();
$result = $sth->fetchAll();

我注意到,即使main_products_common_dimensions表中的列是character_varying,如果我使用,我也会返回相同/正确的结果集

$w_ft = 36; 
...
$sth->bindParam(':w_ft', $w_ft, PDO::PARAM_INT);

$w_ft = "36"; 
...
$sth->bindParam(':w_ft', $w_ft, PDO::PARAM_STR);

$w_ft = "36"; 
...
$sth->bindParam(':w_ft', $w_ft, PDO::PARAM_INT);

$w_ft = 36; 
...
$sth->bindParam(':w_ft', $w_ft, PDO::PARAM_STR);

也就是说,无论我如何绑定参数_INT_STR或设置变量(整数或字符串(,数据都会正确返回。这是正常行为吗?

发件人http://php.net/manual/en/pdostatement.bindparam.php,我看到参数数据类型解释为

使用PDO::PARAM_*常量的参数的显式数据类型。要从存储过程返回INOUT参数,请使用OR运算符为data_type设置PDO::PARAM_INPUT_OUTPUT位参数

什么是"从存储过程返回INOUT参数"?这有关系吗?这是否意味着我没有使用存储过程?长度似乎是可选的,尽管它的解释中没有说明这一点。提供它有好处吗?

正如你所看到的,我对此还很陌生,只是想了解一下。非常感谢

PDO::PARAM_INTPDO::PARAM_STR在传递给bindParam()时表示驱动程序可以自由忽略。

查看PDO pg驱动程序的源代码,除了PDO_PARAM_LOB被特殊处理外,所有类型都被引用为字符串(即,在引号之间并传递给libpq的PQescapeStringConn函数(

您还应该注意PDO::ATTR_EMULATE_PREPARES属性,该属性控制在后台使用的方法。当false时,PQprepare()与实际的查询外参数一起使用。如果是true,则参数值被注入到传递给非参数化PQexec()的SQL中。从技术上讲,这是完全不同的,因此根据此属性,您可能会在拐角情况或错误情况下看到不同的行为。

$w_ft = 36; 
...
$sth->bindParam(':w_ft', $theId, PDO::PARAM_INT);

应该是

$w_ft = 36; 
...
$sth->bindParam(':w_ft', $w_ft, PDO::PARAM_INT);

这是因为postgres在与整数列进行比较时接受整数的引用。

因此,如果您的id列是int,那么这两个查询的工作原理相同:

SELECT * FROM mytable WHERE id = 1;
SELECT * FROM mytable WHERE id = '1';

PDO::PARAM_*常量所做的是修改对值进行引用/转义的方式,并且与值的数据类型无关。如果需要,Php还会进行类型转换。如果选择PDO::PARAM_INT,则说明DBMS驱动程序$id的值是一个整数,应将其转义为整数,因此在将值放入查询时不会在其周围添加引号。

$id = 1;
$sth = $db->prepare("SELECT * FROM mytable WHERE id = :id");
$sth->bindParam(':id', $id, PDO::PARAM_INT);
// resulting query would be SELECT * FROM mytable WHERE id = 1;
$sometext = "hello";
$sth = $db->prepare("SELECT * FROM mytable WHERE id = :id");
$sth->bindParam(':id', $sometext, PDO::PARAM_INT);
// in this case, $sometext will be casted to an integer, that will result in (int)0
// resulting query would be SELECT * FROM mytable WHERE id = 0;
$sometext = "hello";
$sth = $db->prepare("SELECT * FROM mytable WHERE id = :id");
$sth->bindParam(':id', $sometext, PDO::PARAM_STR);
// in this case, $sometext is already a string, and strings should be quoted
// resulting query would be SELECT * FROM mytable WHERE id = 'hello';

此外,关于bindParam的INOUT参数,如果您不打算使用存储过程的INOUT或OUT参数(例如,传递对函数调用的引用,而不是在函数内部设置(,则可能最好使用bindValue。使用bindValue,您可以将函数的结果或任何常数值作为要绑定的值,而不需要放置变量。

$sth->bindValue(':something', 5);
$sth->bindValue(':something_else', $foo->bar());