PHP PDO::bindParam() 数据类型.. 它是如何工作的?
Posted
技术标签:
【中文标题】PHP PDO::bindParam() 数据类型.. 它是如何工作的?【英文标题】:PHP PDO::bindParam() data types.. how does it work? 【发布时间】:2010-10-24 10:15:09 【问题描述】:我想知道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 法拉利 23 250 GTO 法拉利
这意味着如果我没有改变 是否有第三个参数。要么 也许我错过了什么。有人可以 告诉我更多?或者只是可以有人 告诉我在哪里可以找到信息 关于它。
问候,
赛勒斯
这正是我的情况。我的想法哪里出了问题?
【问题讨论】:
“我预计我的数据库中会出现 PHP 错误或整数。”我也是 【参考方案1】:PDO::PARAM_INT 对 INSERT 查询至少有一个影响:布尔值被转换为 0 或 1。就像 in
$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) 转换为长(参数->参数);
【讨论】:
哦..我想知道这种效果是否真的有用..其他数据类型呢?字符串等? 我还没有找到这些功能的可靠文档。因此,我可以浏览 /ext/pdo* 中的所有代码 ...或者根本不依赖该参数进行 INSERT、UPDATE... 查询。 好的,我会尝试 SELECT 查询,看看“问题”是否也影响到它们......无论如何,data_type 声明即使对清理/流程也很有用-控制 INSERT 查询。【参考方案2】:我用 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();
【讨论】:
【参考方案3】:在其他语言的其他 DB 抽象框架中,它可用于确保您对内联值进行了正确的转义(对于不支持正确绑定参数的驱动程序)以及通过使确定数字是适当的二进制打包(给定协议支持)。它看起来像在 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(或者你什么都不说,因为这是默认值)并且你的数据的内部类型是一个双精度类型,那么它会使用一种方法将它变成一个字符串,如果它不是double 然后它将使用不同的方法将其转换为字符串。
如果你说它是一个 int,但它实际上是一个 bool,那么它会将它转换为一个 long。
如果你说它是一个布尔值,但它实际上是一个数字,那么它会将它转换为一个真正的布尔值。
这就是我在查看 stmt 源代码时(快速)看到的全部内容,我想一旦您将参数传递给驱动程序,它们就可以发挥额外的作用。所以,我猜你得到的只是一点点做正确的事,以及司机之间的大量行为模棱两可和差异。
【讨论】:
Doh,我发布了忍者。我想我只是回答慢^^。【参考方案4】:所以我决定深入研究 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::PARAM_STR 将您提供的任何内容转换为除 null 之外的字符串。 PDO::PARAM_INT 将 bool 转换为 long PDO::PARAM_BOOL 将 long 转换为 bool就是这样。没有其他任何东西被转换。 PDO 使用 PARAM 标志来格式化 SQL,而不是强制转换数据类型。
【讨论】:
"PDO::PARAM_STR 将你给它的任何东西转换成一个字符串" 除了 NULL以上是关于PHP PDO::bindParam() 数据类型.. 它是如何工作的?的主要内容,如果未能解决你的问题,请参考以下文章
用于“IN”语句的变量/字符串的 PHP PDO bindParam...? [复制]
PDO::bindParam 在 foreach 循环中,所有值都设置为相同吗?