除非我遗漏了一些非常明显的东西,否则我希望$ data1和$ data2的值相同?但出于某种原因,当我运行这个场景两次(每次调用函数运行一次,所以我调用函数两次)时,会产生不同的结果。
调用1:PDO =空白,Sprintf =返回3行
调用2:PDO = 1行,Sprintf = 4行(包括PDO行)
有人可以告诉我我错过了什么,或者为什么这些可能会返回不同的结果?
$sql = "SELECT smacc.account as Smid,sappr.*,CONCAT('$domain/',filepath,new_filename) as Image
FROM `{$dp}table`.`territories` pt
JOIN `{$dp}table`.`approvals` sappr ON pt.approvalID = sappr.ID
JOIN `{$dp}table`.`sm_accounts` smacc ON pt.ID = smacc.posted_territory_id
LEFT JOIN `{$dp}table`.`uploaded_images` upimg ON pt.imageID = upimg.ID
WHERE postID = %s AND countryID = %s AND smacc.account IN (%s) AND languageID = %s";
echo sprintf($sql,$postID,$countryID,implode(',',$accs),$langID);
$qry1 = $db->prepare(str_replace('%s','?',$sql));
$qry1->execute(array($postID,$countryID,implode(',',$accs),$langID));
$data1 = $qry1->fetchAll();
print'<pre><h1>PDO</h1>';print_r($data1);print'</pre>';
$qry2 = $db->query(sprintf($sql,$postID,$countryID,implode(',',$accs),$langID));
$data2 = $qry2->fetchAll();
print'<pre><h1>Sprintf</h1>';print_r($data2);print'</pre><hr />';
答案 0 :(得分:1)
问题的根源是implode(',',$accs)
函数。
当您使用sprintf()
时,它将生成一个逗号分隔列表,该列表将被注入查询字符串。
结果将是这样的:
smacc.account IN (1,2,3,4,5)
当您使用PDO绑定相同列表时,它会将其作为一个值处理(字符串:&#39; 1,2,3,4,5&#39;)。 &#34;结果&#34;会是这样的:
smacc.account IN ('1,2,3,4,5')
注意撇号! - &GT;查询不完全相同。
简而言之,当您使用PDO和绑定参数时,必须单独绑定每个值(不能将列表作为字符串传递)。
您可以根据输入数组生成查询,如下所示:
$query = ... 'IN (?' . str_repeat(', ?', count($accs)-1) . ')' ...
// or
$query = ... 'IN (' . substr(str_repeat('?,', count($accs)), 0, -1) . ')'
这将为数组中的每个输入值添加可绑定参数位置。现在,您可以单独绑定参数。
$params = array_merge(array($postID, $countryID), $accs, array($langID));
$qry1->execute($params);
答案 1 :(得分:0)
是的,因为Kris已经提到这个问题是查询的IN部分。以下链接上的示例5有助于解决此问题:http://php.net/manual/en/pdostatement.execute.php。我尝试使用bindParam(),但似乎没有用,所以将使用例5。