Работа с базами данных в PHP: таблицы и запросы

Раздел: Базы данных -> Работа с базами данных SQL в PHP

Работа с таблицами SQL в PHP

Взаимодействие с реляционными базами данных (MySQL, PostgreSQL, SQLite) из PHP происходит через выполнение SQL-запросов: создание таблиц, вставка, выборка, обновление и удаление записей. Для безопасной и эффективной работы используются специальные расширения: PDO или MySQLi. Ниже рассмотрены основные подходы с примерами кода и разбором типичных проблем.

Как выполнять SQL-запросы к таблицам максимально безопасно и удобно?

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


<?php
$dsn = 'mysql:host=localhost;dbname=testdb;charset=utf8mb4';
$user = 'root';
$pass = '';
$options = [
    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES   => false,
];

try {
    $pdo = new PDO($dsn, $user, $pass, $options);
} catch (PDOException $e) {
    echo 'Подключение не удалось: ' . $e->getMessage();
    exit;
}

// Создание таблицы
$pdo->exec('CREATE TABLE IF NOT EXISTS users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    email VARCHAR(255) UNIQUE NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)');

// Подготовленный запрос для вставки
$stmt = $pdo->prepare('INSERT INTO users (name, email) VALUES (:name, :email)');
$stmt->execute(['name' => 'Иван Петров', 'email' => 'ivan@example.com']);

// Выборка с параметром
$stmt = $pdo->prepare('SELECT * FROM users WHERE id = :id');
$stmt->execute(['id' => 1]);
$user = $stmt->fetch();
echo $user['name'];
?>
  

Php class sql (класс для работы с sql в php)

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

  • Ошибка подключения из-за неверного DSN, имени пользователя или пароля. Решение: проверять данные, использовать блок try-catch.
  • Исключение PDOException при синтаксической ошибке в SQL. Решение: включать режим исключений (ERRMODE_EXCEPTION) и читать сообщение.
  • Проблемы с кодировкой (например, русские символы отображаются как '???'). Решение: указывать charset=utf8mb4 в DSN.
  • Неявное эмуляция подготовленных запросов может приводить к инъекциям в некоторых версиях. Решение: отключать эмуляцию (ATTR_EMULATE_PREPARES = false).

Как работать с MySQL через объектно-ориентированный интерфейс MySQLi?

Расширение MySQLi в ООП-стиле также поддерживает подготовленные запросы. Пример подключения и создания таблицы:


<?php
$mysqli = new mysqli('localhost', 'root', '', 'testdb');
if ($mysqli->connect_error) {
    die('Ошибка подключения: ' . $mysqli->connect_error);
}

$mysqli->set_charset('utf8mb4');

// Создание таблицы
$sql = 'CREATE TABLE IF NOT EXISTS products (
    id INT AUTO_INCREMENT PRIMARY KEY,
    title VARCHAR(255) NOT NULL,
    price DECIMAL(10,2) NOT NULL
) ENGINE=InnoDB';
if (!$mysqli->query($sql)) {
    echo 'Ошибка создания таблицы: ' . $mysqli->error;
}

// Подготовленная вставка
$stmt = $mysqli->prepare('INSERT INTO products (title, price) VALUES (?, ?)');
$stmt->bind_param('sd', $title, $price);
$title = 'Ноутбук';
$price = 59999.99;
$stmt->execute();
$stmt->close();

// Выборка
$result = $mysqli->query('SELECT * FROM products');
while ($row = $result->fetch_assoc()) {
    echo $row['title'] . ' - ' . $row['price'] . '<br>';
}
$mysqli->close();
?>
  

Php sql insert (insert в php)

Возможные ошибки:

  • Забыли установить кодировку через set_charset – русские символы могут не сохраниться.
  • Ошибка в bind_param: неверный тип ('s' для строки, 'd' для double, 'i' для integer). Несовпадение типов приводит к пустым значениям.
  • Не проверяется результат query – если запрос не удался, mysqli->error содержит описание.

Как использовать процедурный стиль MySQLi?

Процедурный вариант удобен для быстрых скриптов, но менее нагляден при сложной логике. Пример:


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

$result = mysqli_query($link, 'SELECT * FROM users');
while ($row = mysqli_fetch_assoc($result)) {
    echo $row['name'] . '<br>';
}
mysqli_free_result($result);
mysqli_close($link);
?>
  

Php ms sql (работа с ms sql в php)

Частые затруднения:

  • Путаница между функциями: mysqli_query, mysqli_fetch_array, mysqli_fetch_assoc – легко ошибиться в имени.
  • Не вызывается mysqli_free_result для освобождения памяти при больших результатах.
  • Подготовленные запросы в процедурном стиле громоздкие (mysqli_stmt_bind_param), что повышает вероятность ошибок.

Как работать с SQLite через PDO?

SQLite – файловая база данных, идеальна для небольших проектов. Подключение и создание таблицы:


<?php
$dsn = 'sqlite:/path/to/database.sqlite';
$pdo = new PDO($dsn);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$pdo->exec('CREATE TABLE IF NOT EXISTS notes (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    content TEXT NOT NULL,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP
)');

$stmt = $pdo->prepare('INSERT INTO notes (content) VALUES (:content)');
$stmt->execute(['content' => 'Привет, SQLite!']);

$rows = $pdo->query('SELECT * FROM notes')->fetchAll();
foreach ($rows as $row) {
    echo $row['content'] . '<br>';
}
?>
  

Специфические проблемы:

  • Файл базы данных должен быть доступен для записи веб-серверу. Ошибка 'unable to open database file' – проверить права.
  • SQLite не поддерживает FOREIGN KEY по умолчанию (требуется PRAGMA foreign_keys = ON).
  • Одновременная запись может блокироваться – SQLite не рассчитан на высокие нагрузки.
- Php sql table (работа с таблицами sql в php)
- Php sql connect (подключение к sql в php)
- Php database sql (работа с базами данных sql в php)

Дополнительные примеры и углублённые приёмы

Ниже приведены расширенные сценарии, которые часто встречаются при работе с таблицами SQL в PHP.

Пример

<?php
// Пример 1: Транзакции в PDO
$pdo->beginTransaction();
try {
    $pdo->exec('UPDATE accounts SET balance = balance - 100 WHERE id = 1');
    $pdo->exec('UPDATE accounts SET balance = balance + 100 WHERE id = 2');
    $pdo->commit();
} catch (Exception $e) {
    $pdo->rollBack();
    echo 'Ошибка транзакции: ' . $e->getMessage();
}
?>
Результат: баланс переведён со счёта 1 на счёт 2. Если одно из обновлений не удалось, изменения откатываются.
Пример

<?php
// Пример 2: Выборка с JOIN
$sql = 'SELECT u.name, o.amount, o.order_date
        FROM users u
        INNER JOIN orders o ON u.id = o.user_id
        WHERE u.status = :status';
$stmt = $pdo->prepare($sql);
$stmt->execute(['status' => 'active']);
$orders = $stmt->fetchAll();
foreach ($orders as $order) {
    echo $order['name'] . ' - ' . $order['amount'] . ' - ' . $order['order_date'] . '<br>';
}
?>
Пример вывода:
Иван Петров - 1500.00 - 2025-03-15
Мария Смирнова - 2300.50 - 2025-03-14
Пример

<?php
// Пример 3: Вставка нескольких строк за один запрос (PDO)
$pdo->beginTransaction();
$stmt = $pdo->prepare('INSERT INTO products (title, price) VALUES (:title, :price)');
$products = [
    ['title' => 'Книга',      'price' => 499.00],
    ['title' => 'Ручка',      'price' => 89.50],
    ['title' => 'Тетрадь',    'price' => 120.00],
];
foreach ($products as $product) {
    $stmt->execute($product);
}
$pdo->commit();
echo 'Добавлено записей: ' . count($products);
?>
Результат: в таблицу products добавлено 3 строки.
Пример

<?php
// Пример 4: Обновление с проверкой количества затронутых строк
$stmt = $pdo->prepare('UPDATE users SET name = :new_name WHERE id = :id');
$stmt->execute(['new_name' => 'Пётр Иванов', 'id' => 10]);
if ($stmt->rowCount() === 0) {
    echo 'Пользователь с id=10 не найден.';
} else {
    echo 'Имя обновлено.';
}
?>
Вывод: 'Имя обновлено.' или 'Пользователь с id=10 не найден.'
Пример

<?php
// Пример 5: Использование lastInsertId
$stmt = $pdo->prepare('INSERT INTO users (name, email) VALUES (?, ?)');
$stmt->execute(['Анна', 'anna@test.com']);
$newId = $pdo->lastInsertId();
echo 'Новый ID: ' . $newId;
?>
Вывод: 'Новый ID: 42' (зависит от автоинкремента).
Пример

<?php
// Пример 6: Постраничная выборка (LIMIT и OFFSET)
$page = 2;
$perPage = 10;
$offset = ($page - 1) * $perPage;
$stmt = $pdo->prepare('SELECT * FROM articles ORDER BY id DESC LIMIT :limit OFFSET :offset');
$stmt->bindValue('limit', $perPage, PDO::PARAM_INT);
$stmt->bindValue('offset', $offset, PDO::PARAM_INT);
$stmt->execute();
$articles = $stmt->fetchAll();
?>
Результат: на странице 2 отобразятся статьи с 11 по 20.
Пример

<?php
// Пример 7: Удаление с проверкой существования
$stmt = $pdo->prepare('DELETE FROM temp_data WHERE expires < NOW()');
$stmt->execute();
echo 'Удалено строк: ' . $stmt->rowCount();
?>
Вывод: 'Удалено строк: 5' (если просроченных записей было 5).

Эти примеры демонстрируют типовые операции: транзакции, связи между таблицами, массовые вставки, проверки, пагинацию и очистку данных. Каждый блок кода сопровождается комментариями, облегчающими понимание.

Работа с таблицами SQL в PHP - comments

En
Php sql table (php)