2011-05-20 90 views
12
$statement = $db->prepare('SELECT blah FROM blah_table WHERE blahID IN (:a, :b, :c)'); 

如果参数的数量在运行时间之前是未知的,该怎么办?我能想到的唯一办法就是构建一个hacky类型的sql字符串,以根据需要创建多个参数占位符。PDO绑定未知数量的参数?

+0

真的,这是一个新问题的重复? – Kickstart 2016-07-08 13:12:33

+0

@Kickstart为什么不 - 如果其他问题很好,并提供有用的答案。 – Eiko 2016-07-08 13:33:00

+0

@Eiko - 为什么在同一个人回答重复并在此给出与现有答案基本相同的答案几年后重复标记? – Kickstart 2016-07-08 13:53:10

回答

4

可以打造的 “IN(...)” 动态字符串:

$in_string = '('; 
foreach ($array_of_parameters as $parameter) { 
    $in_string .= ':' . chr($i + 97) . ','; // Get the ASCII character 
} 
$in_string = substr($in_string, 0, -1) . ')'; 

$statement = $db->prepare("SELECT blah FROM blah_table WHERE blahID IN ($in_string)"); 
+8

你为什么要经历使用命名占位符的麻烦?用一个 ?没有额外的工作就可以工作吗? – Paystey 2011-05-21 02:11:07

11

不是很好,循环是循环不定次数的语言的一部分。


$values = array('val1', 'val2'); 
$sql = 'SELECT * FROM Table Where column IN('; 
$params = array(); 
foreach ($values as $val) 
{ 
    $params[] = '?'; 
    $binds[] = $val; 
} 
$prep = $db->prepare($sql . join(', ', $params) . ')'); 
$i = 0; 
foreach($binds as $bind){ 
    $prep->bindValue(++$i, $bind); 
} 
$prep->execute(); 

循环遍历每个需要绑定的值,创建一个绑定对象数组,在追加SQL后循环。

2

又一个这样做的短路。

$values = array(1, 2, 3, 4); 
$sql = "SELECT * 
      FROM table 
     WHERE column IN (" . join(',', array_map(function() { return '?'; }, $values)) . ")"; 
$db->prepare($sql); 
$db->execute($values); 
+0

如果你给你的代码提供一些解释,它将会非常感激。 – 2014-06-29 13:23:00

+0

@IllegalArgument您想要解释哪个部分? [join](http://php.net/manual/en/function.join.php),[array_map](http://php.net/manual/en/function.array-map.php) – 2015-09-15 22:35:42

+1

@IllegalArgument他利用了array_map接受将在每个数组元素上执行的回调函数的事实。虽然= =有点矫枉过正)就像''?' 。 str_repeat(',?',count($ arr) - 1)'或'rtrim(str_repeat('?,',count($ arr)),',')'就足够好了,因为你只需要一个问题标记数组的每个元素。 – nimmneun 2016-03-25 10:42:09

0

一种没有显式循环但是给出特定标记而不是问号的方法。

$values_array = array(1, 3, 5, 7, 11); 
$sql = "SELECT * 
      FROM table 
     WHERE column IN (" . implode(",", array_map(function($in){return ':a'.$in;}, range(1, count($values)))) . ")"; 
$prep = $db->prepare($sql); 
$i = 1; 
foreach($values_array as $key=>$value) 
{ 
    $prep->bindValue(':a'.$i++, $values_array[$key]); 
} 

这使用范围生成的数字从1的阵列到阵列中的项目的数目,然后array_map改变这些数字与预先考虑他们,一个字符(在这种情况下只是一个)。

只是因为试图调试使用问号而失败的东西而造成的。问题原来是在其他地方(由于循环数组来绑定值,并使用变量的引用存在问题,该变量在数组的每次迭代中都发生了变化 - 因此在每个迭代中都有相同的值绑定职位),但认为这可能对某人有用。

+0

希望它能帮助任何人。由于在这种情况下使用命名占位符只是一个[...]。尽管为了避免显式循环,您只需避免它,如其他答案所示。 – 2016-07-08 12:59:51

+0

在noddy的情况下也许是正确的,但是如果你有(例如)一对联合查询,每个查询都有相同的参数被传递,能够绕过parms一次,将它们绑定到特定的占位符,而不仅仅是按照问号很有用。 – Kickstart 2016-07-08 13:21:12