2014-01-14 3 views
2

Я новичок в PHP. Я пытаюсь отобразить детали сотрудников в виде таблицы. Но while($row = $result->fetchObject()) часть не исполняется, так как $result->fetchObject() возвращает false. Как это связано с $rows = $result->fetchAll();? Вот фрагмент кода.PDO fetchObject() после fetchall(). return false

$sql = "SELECT id, name, designation FROM employees"; 

if ($result = $pdo->query($sql)) { 
    $rows = $result->fetchAll(); 
    $num_rows = count($rows); 

    if ($num_rows > 0) { 
     echo "<table>\n"; 
     echo " <tr class=\"heading\">\n"; 
     echo " <td>ID</td>\n"; 
     echo " <td>Name</td>\n"; 
     echo " <td>Designation</td>\n";  
     echo " </tr>\n"; 

     while($row = $result->fetchObject()) { 
      echo " <tr>\n"; 
      echo " <td>" . $row->id . "</td>\n"; 
      echo " <td>" . $row->name . "</td>\n"; 
      echo " <td>" . $row->designation . "</td>\n"; 
      echo " </tr>\n"; 
     } 
     echo "</table>"; 
    } else { 
     echo "No employees in database."; 
    } 

else { 
    echo "ERROR: Could not execute $sql. " . print_r 
    ($pdo->errorInfo()); 
} 
+5

Когда вы вызываете 'fetchAll()', вы уже выбрали все! Итак, 'fetchObject()' ничего не осталось, чтобы извлечь. Просто зациклируйте на '$ rows'. –

+3

... как в 'foreach ($ rows as $ row)' вместо цикла while(). Вам также может потребоваться установить тип выборки при вызове 'fetchALL()', если вы не задали его по умолчанию: '$ rows = $ result-> fetchAll (PDO :: FETCH_OBJ)'. Тогда вам не нужно ничего менять в теле цикла. –

+1

@MichaelBerkowski Вы должны опубликовать это как вопрос. – Barmar

ответ

7

документации PDO является немного запутанным на это, но метод PDOStatement::fetch() и его кузен fetchAll() возвращение false, когда нет больше строк доступны для возврата. Документы говорят, что он возвращает falseпри ошибке, а отсутствие доступных строк считается неудачным.

Вашего первоначальный вызов fetchAll() получает все строки из объекта PDOstatement результата и больше нет для fetchObject() вызова для получения так он возвращает false.

Вам нужен только ваш первоначальный вызов fetchAll(), но вам может потребоваться установить его тип выборки PDO::FETCH_OBJ, если вы ранее не задавали тип выборки по умолчанию для вашего соединения.

Затем вы можете заменить петлю while простой петлей foreach над массивом $rows, который у вас уже есть. Это имеет дополнительное преимущество, разделяя вашу логику отображения от бизнес-логики запросов к базе данных немного больше:

if ($result = $pdo->query($sql)) { 
    // Fetch them now, as objects 
    $rows = $result->fetchAll(PDO::FETCH_OBJ); 
    $num_rows = count($rows); 

    if ($num_rows > 0) { 
     echo "<table>\n"; 
     echo " <tr class=\"heading\">\n"; 
     echo " <td>ID</td>\n"; 
     echo " <td>Name</td>\n"; 
     echo " <td>Designation</td>\n";  
     echo " </tr>\n"; 

     // $rows now has everything you need, just loop over it 
     foreach ($rows as $row { 
      echo " <tr>\n"; 
      echo " <td>" . htmlspecialchars($row->id) . "</td>\n"; 
      echo " <td>" . htmlspecialchars($row->name) . "</td>\n"; 
      echo " <td>" . htmlspecialchars($row->designation) . "</td>\n"; 
      echo " </tr>\n"; 
     } 
     echo "</table>"; 
    } else { 
     echo "No employees in database."; 
    } 

else { 
    echo "ERROR: Could not execute $sql. " . print_r 
    ($pdo->errorInfo()); 
} 

Отметим также, что я добавил вызовы htmlspecialchars() при записи вывода в формате HTML. Это всегда рекомендуется, так что символы, такие как < > &, которые имеют особое значение в HTML, правильно кодируются и позволяют избежать межсайтовых скриптовых уязвимостей, если эти значения возникли как пользовательский ввод.

Смежные вопросы