#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
. Вот почему вы получаете сообщение об ошибке.
Есть несколько способов решить эту проблему.
- Не используйте
while
цикл. Нет причин использовать его в вашем примере.foreach ($sth as $row) { echo $row['YEAR']; }
- Если все, что вам нужно, — это один столбец, то нет причин извлекать массив.
while( $year = $sth->fetchColumn() ) { echo $year; }
- Установите режим выборки при выполнении запроса или использовании
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
это более уместно