PDO PHP bindValue不起作用(PDO PHP bindValue doesn'

2019-07-18 10:50发布

我知道这已被要求1000倍,但由于某些原因,我继续一声我的头agains墙..

这工作:

$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();

这并不:

$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();

我在想什么? 谢谢

Answer 1:

问题就在这里:

$sql = $sql . 'WHERE a.regGUID in ( :regGUID ) and ';
$stmt->bindValue(':regGUID', $regGUID, PDO::PARAM_STR);

我假设$ regGUID是一个逗号分隔的加引号字串。

每个查询参数只接受单个标量值。 值的未列出

所以,你有两个选择:

  1. 继续插值$ regGUID字符串,即使您使用其它标值的参数。 但你还是要小心,避免SQL注入,所以你必须正确地形成$ regGUID字符串。 你不能只是调用PDO ::引用()在整个字符串,这将使它包含的UUID和逗号一个单引号字符。 你必须确保每个UUID字符串逃过并单独报价,然后一起破灭的列表,并将其插值到IN子句。

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

     $regGUIDs = explode(',', $regGUID); $params = array_fill(1, count($regGUIDs), '?'); $sql = $sql . ' WHERE a.regGUID in ( ' . implode(',', $params) . ' ) and '; 

你可以在阵列的循环bindValue(),但请记住,其他参数也应通过位置的约束,叫不上名字。 PDO都有漏洞,使人们不开心的时候,你尝试在同一查询混合的两种不同风格的参数。

代替使用bindValue的(),我传递参数值的数组,以PDOStatement对象::执行(),它是要容易得多。

$paramValues = $regGUIDs;
$paramValues[] = $game;
$results = $stmt->execute($paramValues);


Answer 2:

这确实已被要求1000倍。

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

您可以选择使用尽可能多的占位符,形成()语句,你必须投入,然后绑定逐一尽可能多的项目。

为了缓解这个任务可以使用一些辅助功能。

再说了,使用SafeMysql库这段代码可以写成

$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已经包含了所有的请求数据,而无需任何进一步的处理。



Answer 3:

什么是内容$regGUID ? 由于您使用的是in条款,我怀疑一个逗号分隔的列表。

绑定到参数的变量是不喜欢代该字符串到查询; 这就像告诉MySQL的如何使用您的实际PHP变量。 所以,如果你喜欢一个字符串绑定'1,2,3'的查询参数,它保持作为一个字符串,而没有重新解释为数字列表。

因此,如果$regGUID是像"'AAA1', 'BBB2'" ,第一个查询变得

... WHERE a.regGUID in ( 'AAA1', 'BBB2' ) ...

但你的第二个查询更喜欢

... WHERE a.regGUID in ( '\'AAA1\', \'BBB2\'' ) ...

这等于说

... WHERE a.regGUID = '\'AAA1\', \'BBB2\'' ...


Answer 4:

正如其他人的状态,你只能绑定一个标值的占位符。 因此,这意味着你实际上需要一个占位符,为您的每一个值IN声明。 我通常做像下面这样。 应当指出的是,虽然我从来没有使用bindValue所以如果有关于有是那么下面可能需要修改一样的mysqli引用的东西规则:

$regGUIDPlaceholders = array();

// prepare the placeholders
// assume regGUID is an array - if its a string then explode on whatever to make it an array
foreach($regGUID as $k => $v) {
   $placeholder = ':regGUID' . $k;
   $regGUIDPlaceholders[$key] = $value;
}

// prepare the IN statememnt
$in = sprintf('IN (%s)', implode(',', array_keys($regGUIDPlaceholders)));

$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 ';

// USE the IN statement dynamically prepared above
$sql = $sql . 'WHERE a.regGUID '. $in . ' and ';

$sql = $sql . 'a.playerCode=b.playerCode and a.gameCode = :game order by a.eventTime desc, a.actionCode asc'; 

$stmt = $db->prepare($sql);

// bind each GUID to its placeholder
foreach($regGUIDPlaceholders as $placeholder => $value) {
   $stmt->bindValue($placeholder, $value, PDO::PARAM_STR);
}

$stmt->bindValue(':game', $game, PDO::PARAM_STR);
$results = $stmt->execute();


文章来源: PDO PHP bindValue doesn't work