Читаем список строк из MySQL в PHP: цикл и вывод

Задача простая и частая: есть таблица, надо вывести список строк на страницу. Например, список пользователей: ID и имя. Разберём по шагам, чтобы было понятно, что за чем идёт и почему именно так.

Подключение к базе через PDO

php
$dsn = 'mysql:host=localhost;dbname=testdb;charset=utf8mb4';
$user = 'db_user';
$pass = 'db_pass';
 
$pdo = new PDO($dsn, $user, $pass, [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
]);

Что здесь происходит:

  • $dsn — это строка подключения. В ней указано: драйвер mysql, хост (host=localhost), имя базы (dbname=testdb) и кодировка (charset=utf8mb4).
    Кодировка utf8mb4 — обязательный момент: она поддерживает полный набор Unicode, включая эмодзи и редкие символы. Если поставить просто utf8, часть символов может отображаться некорректно.
  • $user и $pass — учётные данные для доступа к базе. В реальных проектах эти значения не хранят прямо в коде, а выносят в конфигурационный файл или переменные окружения.
  • new PDO(...) — создаёт объект соединения с базой данных.
  • Опция PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION задаёт режим обработки ошибок: при любой ошибке (неверный пароль, недоступная база, ошибка запроса) будет выброшено исключение. Это удобно для отладки: ошибка не «проглотится», а сразу станет заметной.

Выполнение запроса

php
$stmt = $pdo->query('SELECT id, name FROM users LIMIT 10');

Разбор:

  • query() — метод для выполнения SQL‑запроса. Его используют, когда в запросе нет подставляемых пользователем значений.
  • SELECT id, name — выбираем только нужные колонки. Это хорошая практика: не стоит использовать SELECT *, если нужны лишь отдельные поля. Так уменьшается объём передаваемых данных и снижается риск ошибок при изменении структуры таблицы.
  • FROM users — указываем, из какой таблицы берём данные.
  • LIMIT 10 — ограничиваем количество возвращаемых строк. Это полезно, если таблица большая: так мы не загружаем лишние данные и не создаём лишнюю нагрузку.

Результат выполнения query() сохраняется в переменной $stmt. Это объект, который содержит результат запроса и позволяет получать строки по одной.


Перебор строк в цикле и вывод на экран

php
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
    echo 'ID: ' . htmlspecialchars($row['id']) . ', Имя: ' . htmlspecialchars($row['name']) . '<br>';
}

Как это работает:

  • fetch(PDO::FETCH_ASSOC) — получает следующую строку результата в виде ассоциативного массива, где ключи соответствуют именам колонок ($row['id'], $row['name']).
  • Цикл while продолжает выполняться, пока fetch() возвращает строку. Как только строки заканчиваются, fetch() вернёт false, и цикл завершится.
  • htmlspecialchars() — функция, которая экранирует специальные символы в выводе. Это важно для безопасности: если в данных есть символы вроде <, >, &, они будут преобразованы в HTML‑сущности и не сломают разметку страницы.
  • <br> — простой перенос строки, чтобы каждая запись отображалась на новой строке.

Важное уточнение про безопасность и параметры

Метод query() подходит только для запросов без подстановки пользовательских данных. Если нужно фильтровать данные по значению, которое приходит от пользователя (например, по ID или городу), используют подготовленные выражения.

Пример с параметром:

php
$id = 5; // в реальном коде это может быть (int)$_GET['id']
 
$stmt = $pdo->prepare('SELECT id, name FROM users WHERE id = ? LIMIT 1');
$stmt->execute([$id]);
 
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
    echo 'ID: ' . htmlspecialchars($row['id']) . ', Имя: ' . htmlspecialchars($row['name']) . '<br>';
}

Здесь:

  • prepare() — подготавливает запрос с плейсхолдером ?.
  • execute([$id]) — передаёт значение параметра. Такой подход защищает от SQL‑инъекций: данные не подставляются напрямую в текст запроса, а передаются отдельно.

Что проверить, чтобы код заработал

  1. Сервер базы данных запущен. Если MySQL не работает, подключение не установится.
  2. Учётные данные верны. Логин и пароль должны соответствовать пользователю базы с нужными правами.
  3. Таблица и колонки существуют. Убедитесь, что таблица users и колонки id, name действительно есть в базе.
  4. Кодировка в DSN указана. charset=utf8mb4 должен быть в строке подключения.
  5. Ошибки не выводятся пользователю. В продакшен‑среде исключения лучше не показывать на странице, а записывать в лог. Для этого используют конструкцию try/catch.

Пример минимальной обработки ошибок:

php
try {
    $pdo = new PDO($dsn, $user, $pass, [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
    ]);
 
    $stmt = $pdo->query('SELECT id, name FROM users LIMIT 10');
 
    while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
        echo 'ID: ' . htmlspecialchars($row['id']) . ', Имя: ' . htmlspecialchars($row['name']) . '<br>';
    }
} catch (PDOException $e) {
    // В реальном проекте ошибку пишут в лог, а пользователю показывают нейтральное сообщение
    error_log($e->getMessage());
    echo 'Произошла ошибка при работе с базой данных.';
}

Добавить комментарий