Чтение записей из базы данных в PHP

Раздел: Базы данных PHP -> Вывод данных

Основные подходы к получению данных из базы данных в PHP

Наиболее эффективным речением для извлечения данных из базы данных в современных PHP-приложениях является использование расширения PDO (PHP Data Objects) с подготовленными запросами. Этот способ обеспечивает защиту от SQL-инъекций, поддержку различных СУБД (MySQL, PostgreSQL, SQLite и других) и удобный синтаксис. Пример базового получения всех строк из таблицы users:


<?php
$dsn = 'mysql:host=localhost;dbname=testdb;charset=utf8';
$user = 'root';
$password = '';

try {
    $pdo = new PDO($dsn, $user, $password);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $stmt = $pdo->prepare('SELECT id, name, email FROM users WHERE active = :active');
    $stmt->execute([':active' => 1]);
    $users = $stmt->fetchAll(PDO::FETCH_ASSOC);

    foreach ($users as $user) {
        echo $user['name'] . ' - ' . $user['email'] . "<br>";
    }
} catch (PDOException $e) {
    echo 'Ошибка: ' . $e->getMessage();
}
?>
  

Php данные из бд (получение данных из базы данных php)

Пояснение:

  • Строка DSN задаёт тип базы данных, хост, имя БД и кодировку.
  • Подготовленный запрос (prepare) отделяет логику SQL от данных.
  • Метод execute принимает массив с параметрами, подставляя их безопасно.
  • fetchAll(PDO::FETCH_ASSOC) возвращает все строки в виде ассоциативных массивов.

Типичные проблемы и их решение:

  • Ошибка подключения: Проверить правильность DSN, имя пользователя и пароль. Включить исключения при создании PDO.
  • SQL-инъекция при прямом использовании query: Избегать конкатенации значений в SQL. Всегда использовать подготовленные запросы.
  • Некорректные типы данных в bindParam: Указывать тип параметра (PDO::PARAM_INT и т.д.) при явной привязке.

Как получить данные с помощью mysqli в процедурном стиле?

Этот вариант подходит для старых проектов или быстрых скриптов, где нет необходимости в поддержке разных СУБД. Пример:


<?php
$connection = mysqli_connect('localhost', 'root', '', 'testdb');
if (!$connection) {
    die('Ошибка подключения: ' . mysqli_connect_error());
}

$result = mysqli_query($connection, "SELECT id, name FROM users WHERE active = 1");
if ($result) {
    while ($row = mysqli_fetch_assoc($result)) {
        echo $row['name'] . "<br>";
    }
    mysqli_free_result($result);
} else {
    echo 'Ошибка запроса: ' . mysqli_error($connection);
}
mysqli_close($connection);
?>
  

Shows php name (показ имени в php)

Проблема:

Прямое использование mysqli_query с конкатенацией данных приводит к SQL-инъекциям. Для защиты необходимо применять mysqli_prepare и mysqli_stmt_bind_param.

Как использовать объектно-ориентированный mysqli?

Более современный синтаксис в рамках расширения mysqli:


<?php
$mysqli = new mysqli('localhost', 'root', '', 'testdb');
if ($mysqli->connect_error) {
    die('Ошибка: ' . $mysqli->connect_error);
}

$stmt = $mysqli->prepare('SELECT id, name FROM users WHERE active = ?');
$stmt->bind_param('i', $active);
$active = 1;
$stmt->execute();
$result = $stmt->get_result();

while ($row = $result->fetch_assoc()) {
    echo $row['name'] . "<br>";
}
$stmt->close();
$mysqli->close();
?>
  

вывод mysql php (вывод данных из mysql в php)

Здесь bind_param с типом 'i' (integer) предотвращает инъекции.

Как получить результат в виде объекта, а не массива?

Для PDO можно использовать fetch(PDO::FETCH_OBJ) или fetchAll(PDO::FETCH_OBJ). Для mysqli – fetch_object(). Пример с PDO:


$stmt = $pdo->query('SELECT id, name FROM users');
while ($obj = $stmt->fetch(PDO::FETCH_OBJ)) {
    echo $obj->name;
}
  

Как обработать ошибки при получении данных?

В PDO – режим исключений (ERRMODE_EXCEPTION). В mysqli – проверять возвращаемые значения и вызывать mysqli_error. Всегда закрывать соединения и освобождать результаты.

Ошибки при использовании устаревшего mysql_*:

Функции mysql_* удалены в PHP 7.0. При попытке их использования возникает фатальная ошибка. Необходимо переходить на mysqli или PDO.

- Php вывод страницы (вывод страницы в php)
- Start php html (генерация html)
- Php без html (использование php без html (чистый вывод))

Расширенные примеры получения данных

Пример 1. Именованные плейсхолдеры и выборка с условием IN

Пример

<?php
$ids = [1, 2, 3];
$placeholders = implode(',', array_fill(0, count($ids), '?'));
$stmt = $pdo->prepare("SELECT id, name FROM users WHERE id IN ($placeholders)");
$stmt->execute($ids);
$users = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>
Array
(
    [0] => Array ( [id] => 1 [name] => Ivan )
    [1] => Array ( [id] => 2 [name] => Maria )
    [2] => Array ( [id] => 3 [name] => Petr )
)

Пример 2. Маппинг на пользовательский класс через PDO::FETCH_CLASS

Пример

<?php
class User {
    public int $id;
    public string $name;
    public string $email;
}

$stmt = $pdo->prepare('SELECT id, name, email FROM users WHERE active = ?');
$stmt->execute([1]);
$users = $stmt->fetchAll(PDO::FETCH_CLASS, 'User');
foreach ($users as $user) {
    echo $user->name . "\n";
}
?>
Ivan
Maria
Petr

Пример 3. Пагинация с использованием LIMIT и OFFSET

Пример

<?php
$page = 2;
$perPage = 10;
$offset = ($page - 1) * $perPage;

$stmt = $pdo->prepare('SELECT * FROM posts ORDER BY created_at DESC LIMIT :limit OFFSET :offset');
$stmt->bindValue(':limit', $perPage, PDO::PARAM_INT);
$stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
$stmt->execute();
$posts = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>

Пример 4. Получение одного столбца с помощью fetchColumn

Пример

<?php
$stmt = $pdo->query('SELECT DISTINCT city FROM users');
while ($city = $stmt->fetchColumn()) {
    echo $city . "<br>";
}
?>

Пример 5. Использование транзакций с блокировкой для согласованного чтения

Пример

<?php
$pdo->beginTransaction();
try {
    // Блокировка строк для чтения (FOR UPDATE)
    $stmt = $pdo->prepare('SELECT balance FROM accounts WHERE id = ? FOR UPDATE');
    $stmt->execute([1]);
    $balance = $stmt->fetchColumn();

    // Выполнение обновления
    $pdo->exec('UPDATE accounts SET balance = balance - 100 WHERE id = 1');
    $pdo->commit();
} catch (Exception $e) {
    $pdo->rollBack();
    echo 'Ошибка: ' . $e->getMessage();
}
?>

Пример 6. Ленивая загрузка больших наборов данных с fetch()

Пример

<?php
$stmt = $pdo->prepare('SELECT * FROM logs WHERE date > ?');
$stmt->execute(['2024-01-01']);
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
    // Обработка каждой строки без загрузки всех в память
    processLog($row);
}
?>

Пример 7. Использование MYSQL_ATTR_USE_BUFFERED_QUERY для больших запросов

Пример

<?php
$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
$stmt = $pdo->query('SELECT * FROM huge_table');
foreach ($stmt as $row) {
    // unbuffered query – данные передаются строкой за строкой
}
?>

Пример 8. Получение данных с подсчётом общего количества строк (пагинация + count)

Пример

<?php
$stmtCount = $pdo->prepare('SELECT COUNT(*) FROM users WHERE active = ?');
$stmtCount->execute([1]);
$total = $stmtCount->fetchColumn();

$stmtData = $pdo->prepare('SELECT * FROM users WHERE active = ? LIMIT ? OFFSET ?');
$stmtData->execute([1, $perPage, $offset]);
$data = $stmtData->fetchAll();
?>

Получение данных из базы данных PHP - comments

En
Php данные из бд (php)