首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PDO PHP bindValue不工作

PDO PHP bindValue不工作
EN

Stack Overflow用户
提问于 2013-01-20 00:57:59
回答 4查看 8K关注 0票数 7

我知道这个问题已经被问了1000次了,但由于某种原因,我还是不断地用头撞墙。

这是可行的:

代码语言:javascript
复制
$sql = 'SELECT a.eventCode, a.eventTime, a.teamCode, a.playerCode, b.lastName, b.firstName, b.number, a.xCoord, a.yCoord, a.id ';
$sql = $sql . 'FROM events a, players b ';
$sql = $sql . 'WHERE a.regGUID in ( ' . $regGUID . ' ) and ';
$sql = $sql . 'a.playerCode=b.playerCode and a.gameCode = "' . $game . '" order by a.eventTime desc, a.actionCode asc'; 
$stmt = $db->prepare($sql);
$results = $stmt->execute();

这不是:

代码语言:javascript
复制
$sql = 'SELECT a.eventCode, a.eventTime, a.teamCode, a.playerCode, b.lastName, b.firstName, b.number, a.xCoord, a.yCoord, a.id ';
$sql = $sql . 'FROM events a, players b ';
$sql = $sql . 'WHERE a.regGUID in ( :regGUID ) and ';
$sql = $sql . 'a.playerCode=b.playerCode and a.gameCode = :game order by a.eventTime desc, a.actionCode asc'; 
$stmt = $db->prepare($sql);
$stmt->bindValue(':regGUID', $regGUID, PDO::PARAM_STR);
$stmt->bindValue(':game', $game, PDO::PARAM_STR);
$results = $stmt->execute();

我遗漏了什么?谢谢

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-01-20 01:18:49

问题出在这里:

代码语言:javascript
复制
$sql = $sql . 'WHERE a.regGUID in ( :regGUID ) and ';
$stmt->bindValue(':regGUID', $regGUID, PDO::PARAM_STR);

我假设$regGUID是一个逗号分隔的带引号的字符串列表。

每个查询参数只接受一个标量值。Not lists of values。

所以你有两个选择:

即使您对其他标量值使用参数,

  1. 也会继续对$regGUID字符串进行插值。但是您仍然希望小心避免SQL注入,因此必须正确地形成$regGUID字符串。不能只对整个字符串调用PDO::quote(),这将使它成为包含UUID和逗号的单个带引号的字符串。您必须确保每个UUID字符串都被单独转义和引用,然后将列表一起内爆并将其插入IN子句中。

$regGUIDs = explode(',',$regGUID);$regGUIDs = array_map(function ($g) { return $db->quote($g);},$regGUIDs);$regGUID =explode( ',‘,$regGUIDs);$sql = $sql。“'WHERE a.regGUID in (”.$regGUID。')并将$regGUID添加到数组中,并为数组中的每个元素添加一个查询参数。插入查询参数占位符的动态列表。

$regGUIDs = explode(',',$regGUID);$params = array_fill(1,count($regGUIDs),'?');$sql = $sql。‘其中a.regGUID位于(‘.内爆( ',‘,$params)。‘)和';

您可以在数组的循环中使用bindValue(),但请记住,其他参数也应该按位置绑定,而不是按名称绑定。当您尝试在同一查询中混合两种不同风格的参数时,PDO会有一些错误。

我不使用bindValue(),而是将一个参数值数组传递给PDOStatement::execute(),这要容易得多。

代码语言:javascript
复制
$paramValues = $regGUIDs;
$paramValues[] = $game;
$results = $stmt->execute($paramValues);
票数 5
EN

Stack Overflow用户

发布于 2013-01-20 01:04:50

这确实已经被问了1000次了。

预准备语句只能接受标量值,不能接受SQL查询的任意部分。

你必须使用尽可能多的占位符组成IN()语句,你必须放入尽可能多的项,然后一个接一个地绑定它们。

要简化此任务,可以使用一些helper函数。

比方说,使用SafeMysql library可以将此代码编写为

代码语言:javascript
复制
$sql  = 'SELECT * FROM events a, players b WHERE regGUID in (?a) and';
$sql .= ' a.playerCode=b.playerCode and a.gameCode = ?s';
$sql .= ' order by a.eventTime desc, a.actionCode asc'; 
$results = $db->getAll($sql,$regGUID,$game);

注意,$regGUID应该是一个数组,而不是字符串,并且$results已经包含了所有请求的数据,没有任何进一步的处理。

票数 2
EN

Stack Overflow用户

发布于 2013-01-20 01:06:07

$regGUID的内容是什么?因为您使用的是in子句,所以我怀疑是逗号分隔的列表。

将变量绑定到参数不同于将该字符串替换到查询中;它类似于告诉MySQL如何使用实际的PHP变量。因此,如果将像'1,2,3'这样的字符串绑定到查询参数,它将保留为一个字符串,而不会被重新解释为一组数字。

因此,如果$regGUID类似于"'AAA1', 'BBB2'",那么您的第一个查询将变成

代码语言:javascript
复制
... WHERE a.regGUID in ( 'AAA1', 'BBB2' ) ...

但是您的第二个查询更像是

代码语言:javascript
复制
... WHERE a.regGUID in ( '\'AAA1\', \'BBB2\'' ) ...

这就是说

代码语言:javascript
复制
... WHERE a.regGUID = '\'AAA1\', \'BBB2\'' ...
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14416601

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档