我想知道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 Testarossa Ferrari 23 250 GTO法拉利
这意味着如果我有第三个参数,它不会改变.或许我想念一些东西.有人能容忍我吗?或者只是有人告诉我在哪里可以找到有关它的信息.
问候,
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(或者你根本没有说任何东西,因为这是默认的)并且你的数据的内部类型是一个双,那么它将使用一种方法将其变成一个字符串,如果它不是一个双重的那么它将使用不同的方法将其转换为字符串.
如果你说它是一个int但它真的是一个bool然后它将它转换为long.
如果你说它是一个bool,但它确实是一个数字,那么它会将它转换为真正的布尔值.
这就是我所看到的(快速)查看stmt源码的所有内容,我想一旦你将参数传递给驱动程序,他们就可以做更多的魔术.所以,我猜你得到的只是一些正确的行为,以及很多行为模糊和驱动程序之间的差异.
所以我决定深入研究PHP源代码,这就是我发现的.
static int really_register_bound_param
在版本5.2.9的第329行的ext/pdo/pdo_stmt.c中
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之外的字符串.
PDO :: PARAM_INT将bools转换为long
PDO :: PARAM_BOOL将long转换为bools
而已.没有其他东西被转换.PDO使用PARAM标志格式化SQL以不转换数据类型.
在INSERT查询中,PDO :: PARAM_INT至少有一个效果:布尔值转换为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->parameter); }