PHP PDO::bindParam() 数据类型..它是如何工作的?

问题描述 投票:0回答:4

我想知道

bindParam()
(或
bindValue()
)中的数据类型声明的用途是什么...

我的意思是,我认为如果我定义一个整数参数(

PDO::PARAM_INT
),则该参数必须转换为整数,类似于

$delete->bindParam(1, $kill, PDO::PARAM_INT);
// should work like
$delete->bindParam(1, (int)$kill);

或者如果参数不是声明的类型,至少抛出一个错误。但事实并非如此。

谷歌搜索,我在 php.net 存档中发现:

大家好

我目前正在研究 PDO。确切地 在bindParam()函数上。第三 参数data_type似乎在这里 强制值的类型?但 当我尝试时:

$sql = "INSERT INTO produit (idproduit, nom, marque) VALUES (NULL, :nom, :marque)";
$stmt = $dbh->prepare($sql);
$nom = 'Testarossa'; $marque = 'Ferrari' ;
$stmt->BindValue(':marque',$marque) ;
$stmt->BindParam(':nom',$nom,PDO::PARAM_INT) ;

$stmt->execute(); $nom = '250 GTO' ;
$stmt->execute(); ?>

我本来希望拥有 PHP 我的数据库中有错误或整数。 但在我的数据库中我有:

22 泰斯塔罗萨法拉利 23 250 GTO 法拉利

这意味着如果我 有没有第三个参数。或者 也许我错过了什么。有人可以吗 告诉我更多吗?或者有人可以 告诉我在哪里可以找到信息 关于它。

问候,

赛勒斯

这正是我的情况。我的想法哪里出了问题?

php types pdo prepared-statement
4个回答
33
投票

它可用于确保 PDO 对内联值进行正确的转义(对于不支持正确绑定参数的驱动程序)以及通过确保数字适当地进行二进制打包来提高网络效率(给定协议支持) .

看起来在基础 PDO 中,它没有做太多事情。

if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_STR && param->max_value_len <= 0 && !Z_ISNULL_P(parameter)) {
    if (!try_convert_to_string(parameter)) {
        return 0;
    }
} else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_INT && (Z_TYPE_P(parameter) == IS_FALSE || Z_TYPE_P(parameter) == IS_TRUE)) {
    convert_to_long(parameter);
} else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_BOOL && Z_TYPE_P(parameter) == IS_LONG) {
    convert_to_boolean(parameter);
}

因此,如果您说它是一个字符串(或者如果您什么也没说,因为这是默认值)并且您的数据类型不是 NULL,那么它会将其转换为字符串。

如果你说它是 int 但你绑定了 bool 那么它会将其转换为整数。

如果你说它是一个布尔值,但你绑定了一个数字,那么它会将其转换为真正的布尔值。

当打开模拟模式时,类型提示用于确定如何将其注入到 SQL 字符串中。

此外,PDO 将此信息提供给数据库驱动程序,然后数据库驱动程序可用于根据特定数据库的要求以最佳或正确的方式绑定数据。


23
投票

所以我决定深入研究 PHP 源代码,这就是我发现的。

static int really_register_bound_param
位于 ext/pdo/pdo_stmt.c 版本 8.3.0 第 329 行

if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_STR && param->max_value_len <= 0 && !Z_ISNULL_P(parameter)) {
    if (!try_convert_to_string(parameter)) {
        return 0;
    }
} else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_INT && (Z_TYPE_P(parameter) == IS_FALSE || Z_TYPE_P(parameter) == IS_TRUE)) {
    convert_to_long(parameter);
} else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_BOOL && Z_TYPE_P(parameter) == IS_LONG) {
    convert_to_boolean(parameter);
}

这些是 PDO 在绑定期间所做的转换。

  • PDO::PARAM_STR 将您提供的任何内容转换为除 null 之外的字符串。
  • PDO::PARAM_INT 将布尔值转换为整数
  • PDO::PARAM_BOOL 将长整型转换为布尔型

就是这样。没有其他任何东西被转换。 PDO 使用 PARAM 标志来格式化 SQL,而不是转换数据类型。


6
投票

PDO::PARAM_INT 对 INSERT 查询至少有一种影响:布尔值被转换为 0 或 1。如

$i = true;
$stmt->bindParam(':i', $v, PDO::PARAM_INT);

pdo_stmt.c:

else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_INT && Z_TYPE_P(param->parameter) == IS_BOOL) {
        Convert_to_long(参数->参数);
}


3
投票

我用 BindValue 尝试了相同的操作并得到了相同的结果,因此您看到的行为不仅限于 bindParam。

$stmt->BindValue(':marque', $marque) ;
$stmt->BindValue(':nom', $nom, PDO::PARAM_INT) ;

$stmt->execute();
$nom = '250 GTO';
$stmt->BindValue(':nom', $nom, PDO::PARAM_INT) ;
$stmt->execute(); 
© www.soinside.com 2019 - 2024. All rights reserved.