PDO参数没有通过,但是sprintf是

时间:2014-11-12 09:20:22

标签: php mysql pdo

除非我遗漏了一些非常明显的东西,否则我希望$ 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 />';

2 个答案:

答案 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。