2011-05-20 162 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