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

我想知道是什么bindParam() (或bindValue() )中的数据types的声明用于…

我的意思是,我认为,如果我定义一个整数参数( PDO::PARAM_INT ),参数必须转换为一个整数,类似

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

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

谷歌search,我发现在php.net的档案:

大家好,

我目前正在研究PDO。 完全在bindParam()函数上。 第三个参数data_type似乎是在这里强制的值的types? 但是当我尝试:

 $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 Testarossa法拉利23 250 GTO法拉利

这意味着,如果我有第三个参数没有改变。 或者我想念一些东西。 有人能容忍我更多? 或者只是有人可以告诉我在哪里可以find关于它的信息。

问候,

Cyruss

那正是我的情况。 我的想法在哪里出错?

在其他语言的其他数据库抽象框架中,它可以用于确保您正在为内联值(对于不支持正确的绑定参数的驱动程序)进行适当的转义,并通过确保数字为二进制包装适当(给定的协议支持)。 它看起来在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(或者如果你什么都不说,因为这是默认值),你的数据的内部types是一个双精度型,那么它将使用一种方法将它变成一个string,如果它不是一个double将使用不同的方法将其转换为string。

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

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

这是所有我看到(迅速)看到的源码,我想象一旦你将parameter passing给驱动程序,他们可以做更多的魔法。 所以,我想你所得到的只是在驾驶者之间做一些行为模棱两可的行为。

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

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

 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 :: PARAM_STR把你给它的任何东西都转换为除null以外的string。
  • PDO :: PARAM_INT将bools转换成长整型
  • PDO :: PARAM_BOOL将long转换为bools

而已。 没有别的被转换。 PDO使用PARAM标志来格式化SQL,而不是强制转换数据types。

PDO :: PARAM_INT对INSERT查询至less有一个效果:布尔值被转换为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(param->参数);
 } 

我尝试了与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();