Почему я получаю «Пытаюсь получить доступ к смещению массива по значению типа bool» при использовании цикла while?

#php #arrays #pdo

Вопрос:

У меня есть объект PDO со следующим кодом:

 $query = "SELECT DISTINCT SUBSTR( Date(Date), 1, 4) AS YEAR from Events ORDER BY YEAR DESC;";
$sth = $dbh->query( $query );
while( $row = $sth->fetch( PDO::FETCH_ASSOC )['YEAR'] ) {
  print $row
}
 

Код выполняется, но я получаю

Попытка доступа к смещению массива по значению типа bool

Каково объяснение и есть ли решение?

Комментарии:

1. Объяснение заключается в том, что ваш запрос не удался и вернулся false . Исправление состоит в том, чтобы выяснить, почему это не удалось, и устранить это. Видишь php.net/manual/en/pdo.error-handling.php

Ответ №1:

Способ, которым работает while цикл, заключается в том, что он будет продолжать повторяться до тех пор, пока условие не примет логическое значение true.

PDOStatement::fetch() вернет массив, содержащий данные текущей строки, и переместит внутренний указатель на следующую строку в результате. Если строк больше нет, он возвращается false .

Это означает, что как только вы достигнете конца результата PDO, fetch() он вернется false , и вы не сможете получить доступ к смещению массива false . Вот почему вы получаете сообщение об ошибке.

Есть несколько способов решить эту проблему.

  1. Не используйте while цикл. Нет причин использовать его в вашем примере.
     foreach ($sth as $row) {
        echo $row['YEAR'];
    }
     
  2. Если все, что вам нужно, — это один столбец, то нет причин извлекать массив.
     while( $year = $sth->fetchColumn() ) {
        echo $year;
    }
     
  3. Установите режим выборки при выполнении запроса или использовании setFetchMode() .
     $sth = $dbh->query( $query, PDO::FETCH_COLUMN, 0 );
    foreach ($sth as $year) {
        echo $year;
    }
     

Ответ №2:

Похоже, это тоже работает:

 $sth = $dbh->query( $query );
while( $row = $sth->fetch( PDO::FETCH_ASSOC ))
  print $row['YEAR']
 

Я согласен, что foreach это более уместно