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

2022-08-30 14:32:27

我想知道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错误或一个interger。但是在我的数据库中,我有:

22 Testarossa Ferrari 23 250 GTO Ferrari

这意味着如果我有第三个参数,它就不会改变。或者也许我错过了什么。有人可以多给我一点吗?或者只是有人可以告诉我在哪里可以找到有关它的信息。

问候

赛勒斯

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


答案 1

在其他语言的其他数据库抽象框架中,它可以用于确保对内联值进行正确的转义(对于不支持正确绑定参数的驱动程序),以及通过确保数字适当地二进制打包来提高网络效率(给定协议支持)。它看起来像在PDO中,它没有做太多事情。

   if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_STR && param->max_value_len <= 0 && ! ZVAL_IS_NULL(param->parameter)) {
                if (Z_TYPE_P(param->parameter) == IS_DOUBLE) {
                        char *p;
                        int len = spprintf(&p, 0, "%F", Z_DVAL_P(param->parameter));
                        ZVAL_STRINGL(param->parameter, p, len, 0);
                } else {
                        convert_to_string(param->parameter);
                }
        } else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_INT && Z_TYPE_P(param->parameter) == IS_BOOL) {
                convert_to_long(param->parameter);
        } else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_BOOL && Z_TYPE_P(param->parameter) == IS_LONG) {
                convert_to_boolean(param->parameter);
        }

因此,如果您说它是STR(或者如果您什么都不说,因为这是默认值),并且数据的内部类型是双精度,那么它将使用一种方法将其转换为字符串,如果它不是双精度,那么它将使用其他方法将其转换为字符串。

如果你说它是一个int,但它真的是一个布尔,那么它会把它转换为一个长。

如果你说这是一个布尔值,但它实际上是一个数字,那么它会将其转换为真正的布尔值。

这真的是我(快速)看到的stm源代码,我想一旦你把参数传递到驱动程序中,他们就可以做额外的魔术。所以,我猜你得到的只是一点点正确的事情,以及司机之间的大量行为模糊和差异。


答案 2

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

static int really_register_bound_param在 ext/pdo/pdo_stmt.c 中,位于版本 5.2.9 的第 329 行

if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_STR && param->max_value_len <= 0 && ! ZVAL_IS_NULL(param->parameter)) {
    if (Z_TYPE_P(param->parameter) == IS_DOUBLE) {
        char *p;
        int len = spprintf(&p, 0, "%F", Z_DVAL_P(param->parameter));
        ZVAL_STRINGL(param->parameter, p, len, 0);
    } else {
        convert_to_string(param->parameter);
    }
} else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_INT && Z_TYPE_P(param->parameter) == IS_BOOL) {
    convert_to_long(param->parameter);
} else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_BOOL && Z_TYPE_P(param->parameter) == IS_LONG) {
    convert_to_boolean(param->parameter);
}

这些是 PDO 在绑定期间执行的转换。

  • PDO::P ARAM_STR 将您提供给它的任何内容转换为除 null 之外的字符串。
  • PDO::P ARAM_INT 将布尔斯转换为多头
  • PDO::P ARAM_BOOL 将多头转换为布尔

就是这样。其他任何内容都不会转换。PDO 使用 PARAM 标志来格式化 SQL,而不是强制转换数据类型。


推荐