2016-04-05 39 views
1

我有以下代碼:PHP/PDO - 使用PDO語句多次使用多個的foreach循環時

if(!empty($postCountryAdd)) { 
$sqlQueryLocalityAdd = $dbh->prepare("SELECT DISTINCT locality_add FROM table WHERE country_add = :country_add ORDER BY locality_add ASC"); 
$sqlQueryLocalityAdd->execute(array(':country_add' => $postCountryAdd)); 

echo '<option value="">Select locality</option>'; 
    foreach($sqlQueryLocalityAdd as $localityAddRow) { 
     //while ($localityAddRow = $sqlQueryLocalityAdd->fetch()){ 
     echo '<option value="'; 
     echo $localityAddRow["locality_add"]; 
     echo '">'; 
     echo $localityAddRow["locality_add"]; 
     echo '</option>'; 
    } 
} 

如果我使用foreach($sqlQueryLocalityAdd as $localityAddRow)代碼停止響應。爲什麼我不能多次使用foreach?我該如何修復它?

+2

也許有趣?指出可滾動遊標在mysql中不可用。 http://stackoverflow.com/a/19076778/3184785。 –

+1

你的示例代碼不會失敗,因爲它沒有顯示你有多個foreach塊之後的情況 - 這就是爲什麼人們感到困惑。代碼不會在整個結果集的第一次迭代中停止,有些情況下您還在嘗試第二次完整迭代。 – Ray

回答

0

$sqlQueryLocalityAdd不是一個結果集,它是一個PDOStatement對象,你只能直接遍歷它一次(如由deceze清楚指出)。

​​語句在查詢成功時返回boolean true或false。

如果運行成功,你需要從中查詢後取結果,並遍歷數組返回:

$success = $sqlQueryLocalityAdd->execute(array(':country_add' => $postCountryAdd)); 
    if($success) { 

     $results = $sqlQueryLocalityAdd->fetchAll(); 

     foreach($results as $localityAddRow) { 
      echo '<option value="'; 
      .... 

結果數組$results只是一個香草陣列,這樣你就可以在它多次迭代如你所願。

注意:如果​​返回false,則查詢有問題 - 返回空結果集結果的成功運行查詢仍然會導致true

+0

'PDOStatement''實現Traversable',所以你*可以*直接迭代它! – deceze

+0

@deceze的確如此,好點。似乎無法找到它的具體實現方式的文檔,所以不確定究竟會發生什麼。它是否在場景後執行fetch?有意義的是,它將迭代結果。 – Ray

+2

它是語法糖而不是'while($ row = $ stmt-> fetch())'...... – deceze

0

$sqlQueryLocalityAdd是一個對象,其中在這種情況下 - 我顯示和OP已經使用 -不能迭代通過。 (大膽,所以@deceze可以理解)。

但是,您可以使用foreach循環內的fetchAll()來實現此目的。

您的代碼應該是這個樣子:

[...] 
    if($sqlQueryLocalityAdd->execute(array(':country_add' => $postCountryAdd)): 
     foreach($sqlQueryLocalityAdd->fetchAll() as $row): 
      echo $row['column']; 
      [...] 
     endforeach; 
    endif; 
[...] 

Difference between an array and an Object

+0

你可以''foreach'對象很好,特別是當它們'實現Traversable'時,就像'PDOStatement'一樣。 – deceze

+0

從來沒有見過這樣做,但這回答了他的問題,所以......我將編輯出'唯一'。 @deceze – KDOT

+0

你仍然在說「不能迭代」,這顯然是錯誤的。該OP還(密碼)說,它的工作*一次*(如果我正確解釋問題)。 – deceze

0

的問題是,結果集只能用一次迭代;它會被耗盡,MySQL會丟棄它,並且不能再次迭代它。

我從來沒有真正嘗試過這一點,但創建一個結果集,它可以重複幾次,你需要一個滾動遊標,你應該能夠創造正是如此:

$sqlQueryLocalityAdd = $dbh->prepare(..., [PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL]); 

那麼理論上應該能夠多次迭代結果。

如果這不起作用,請使用$sqlQueryLocalityAdd->fetchAll()將數據提取到數組中,並按需要頻繁迭代。事實上,這似乎是MySQL的唯一選擇:https://stackoverflow.com/a/19076778/476

+1

我終於明白了。 OP的混淆部分只顯示一個foreach塊。它並不會停留在對語句生成的結果集進行初始完整迭代的一個步驟上,但它會因爲某處以後(未在後期中顯示)而正在死亡,他正在嘗試另一個迭代。 – Ray

+0

@丁丁丁丁丁!我們有一個贏家! – deceze