Процесс добавления таблиц в БД через PHP
Создание таблицы в PHP
Как безопасно и надёжно создать таблицу при помощи PDO?
Наиболее эффективный и современный способ - использование расширения PDO (PHP Data Objects). Оно обеспечивает единый интерфейс для разных СУБД (MySQL, PostgreSQL, SQLite и др.) и поддерживает подготовленные выражения, что защищает от SQL-инъекций.
<?php
$dsn = 'mysql:host=localhost;dbname=test;charset=utf8mb4';
$username = 'root';
$password = '';
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
];
try {
$pdo = new PDO($dsn, $username, $password, $options);
$sql = "CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL UNIQUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4";
$pdo->exec($sql);
echo "Таблица создана или уже существует.";
} catch (PDOException $e) {
echo "Ошибка: " . $e->getMessage();
}
?>
Pdo php 8 (pdo в php 8)
Типичные проблемы:
- Неверный DSN - проверьте имя хоста, название базы данных, порт (по умолчанию 3306 для MySQL).
- Отсутствие драйвера PDO для выбранной СУБД - убедитесь, что в php.ini раскомментирована строка
extension=pdo_mysql(или pdo_pgsql, pdo_sqlite). - Конфликт кодировок - всегда указывайте charset в DSN и в CREATE TABLE.
Этот подход подходит для любых проектов, где требуется переносимость между базами данных и современный стиль кода.
Как создать таблицу с помощью MySQLi (процедурный стиль)?
MySQLi - встроенное расширение для работы только с MySQL. Процедурный стиль может быть удобен для быстрых скриптов и начинающих разработчиков.
<?php
$link = mysqli_connect('localhost', 'root', '', 'test');
if (!$link) {
die('Ошибка подключения: ' . mysqli_connect_error());
}
$sql = "CREATE TABLE IF NOT EXISTS products (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(200) NOT NULL,
price DECIMAL(10,2) NOT NULL,
quantity INT DEFAULT 0
)";
if (mysqli_query($link, $sql)) {
echo "Таблица products создана.";
} else {
echo "Ошибка: " . mysqli_error($link);
}
mysqli_close($link);
?>
Php pdo pgsql (pdo для postgresql)
Возможные ошибки:
- Не установлена кодировка соединения - добавьте
mysqli_set_charset($link, 'utf8mb4');после подключения. - Дублирование таблицы - используйте
IF NOT EXISTS, чтобы избежать ошибки.
Целесообразно использовать в легаси-проектах или при уже написанном коде на MySQLi.
Как создать таблицу через MySQLi в объектно-ориентированном стиле?
Объектный подход MySQLi предоставляет более чистый интерфейс и лучше сочетается с современными парадигмами.
<?php
$mysqli = new mysqli('localhost', 'root', '', 'test');
if ($mysqli->connect_error) {
die('Ошибка подключения: ' . $mysqli->connect_error);
}
$mysqli->set_charset('utf8mb4');
$sql = "CREATE TABLE IF NOT EXISTS orders (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
total DECIMAL(15,2) NOT NULL,
status VARCHAR(50) DEFAULT 'pending',
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
)";
if ($mysqli->query($sql)) {
echo "Таблица orders создана.";
} else {
echo "Ошибка: " . $mysqli->error;
}
$mysqli->close();
?>
Php pdo query (выполнение запросов pdo)
Проблемы с внешними ключами:
- Типы столбцов внешнего ключа и ссылочного столбца должны совпадать (например, оба INT).
- Двигатель таблицы должен быть InnoDB, иначе внешние ключи игнорируются.
Как создать таблицу в SQLite через PDO?
SQLite удобен для разработки, тестов или проектов с небольшим объёмом данных, не требующих отдельного сервера.
<?php
$dsn = 'sqlite:'.__DIR__.'/mydb.sqlite';
$pdo = new PDO($dsn);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = "CREATE TABLE IF NOT EXISTS config (
key_name TEXT PRIMARY KEY,
value TEXT NOT NULL
)";
$pdo->exec($sql);
echo "Таблица config в SQLite создана.";
?>
Php pdo error (ошибки pdo)
Особенности SQLite:
- Не поддерживает полностью типы INT, VARCHAR и т.д. - используйте INTEGER, TEXT, REAL.
- Автоинкремент реализуется через
INTEGER PRIMARY KEY AUTOINCREMENT.
Как создать таблицу, загрузив SQL-файл?
Иногда удобно хранить структуру таблиц в отдельном .sql файле и выполнять его из PHP. Это упрощает развёртывание.
<?php
$pdo = new PDO('mysql:host=localhost;dbname=test', 'root', '');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = file_get_contents('schema.sql');
$pdo->exec($sql);
echo "Структура загружена из файла.";
?>
Потенциальные риски:
- Файл может содержать несколько SQL-запросов - PDO::exec() выполнит только первый. Используйте
pdo->exec($sql)только для одного запроса, либо применяйтеpdo->query()в цикле. - Ошибки в SQL-файле сложнее отлаживать - рекомендуется проверять синтаксис отдельно.
Подходит для управления миграциями вручную или в составе CI/CD.
Расширенные примеры создания таблиц
Ниже приведены более сложные и редкие сценарии с полным кодом и результатами.
Пример 1: Создание таблицы с составным первичным ключом и индексами
Таблица для хранения курсов и студентов (многие ко многим).
<?php
$pdo = new PDO('sqlite::memory:');
$pdo->exec('CREATE TABLE enrollments (
student_id INTEGER NOT NULL,
course_id INTEGER NOT NULL,
enrolled_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
grade INTEGER,
PRIMARY KEY (student_id, course_id),
FOREIGN KEY (student_id) REFERENCES students(id),
FOREIGN KEY (course_id) REFERENCES courses(id)
)');
echo "Таблица enrollments создана с составным ключом.";
?>
Таблица enrollments создана с составным ключом.
Пример 2: Создание временной таблицы для сессионных данных
В MySQL временные таблицы существуют до завершения сессии подключения.
<?php
$mysqli = new mysqli('localhost', 'root', '', 'test');
$sql = "CREATE TEMPORARY TABLE temp_log (
log_id INT AUTO_INCREMENT PRIMARY KEY,
message TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)";
if ($mysqli->query($sql)) {
echo "Временная таблица temp_log создана.";
}
$mysqli->close();
?>
Временная таблица temp_log создана.
Пример 3: Создание таблицы с пространственными данными (PostgreSQL + PostGIS)
Требуется установленное расширение PostGIS. Используется PDO.
<?php
$pdo = new PDO('pgsql:host=localhost;dbname=gisdb', 'postgres', 'secret');
$pdo->exec('CREATE EXTENSION IF NOT EXISTS postgis');
$pdo->exec('CREATE TABLE IF NOT EXISTS locations (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
geom GEOMETRY(Point, 4326)
)');
echo "Таблица locations с геометриями готова.";
?>
Таблица locations с геометриями готова.
Пример 4: Создание таблицы с партиционированием (MySQL)
Пример разделения по диапазонам дат.
<?php
$pdo = new PDO('mysql:host=localhost;dbname=test', 'root', '');
$sql = "CREATE TABLE logs (
id INT AUTO_INCREMENT,
log_date DATE,
message TEXT,
PRIMARY KEY (id, log_date)
) PARTITION BY RANGE (YEAR(log_date)) (
PARTITION p_old VALUES LESS THAN (2020),
PARTITION p_medium VALUES LESS THAN (2025),
PARTITION p_future VALUES LESS THAN MAXVALUE
)";
$pdo->exec($sql);
echo "Партиционированная таблица logs создана.";
Партиционированная таблица logs создана.
Пример 5: Создание таблицы из CSV-файла (динамическое определение столбцов)
Функция считывает первую строку CSV и генерирует CREATE TABLE.
<?php
function createTableFromCsv($pdo, $csvFile, $tableName) {
$header = fgetcsv(fopen($csvFile, 'r'));
if (!$header) throw new Exception('Пустой CSV');
$columns = [];
foreach ($header as $col) {
$safeCol = preg_replace('/[^a-zA-Z0-9_]/', '_', $col);
$columns[] = "`$safeCol` TEXT";
}
$colDef = implode(', ', $columns);
$sql = "CREATE TABLE IF NOT EXISTS `$tableName` ($colDef)";
return $pdo->exec($sql);
}
$pdo = new PDO('sqlite:test.db');
createTableFromCsv($pdo, 'data.csv', 'imported_data');
echo "Таблица создана на основе заголовков CSV.";
?>
Таблица создана на основе заголовков CSV.
Пример 6: Создание таблицы с триггерами и хранимыми процедурами (обёрнуто в код)
Триггер автоматически обновляет поле updated_at.
<?php
$pdo = new PDO('mysql:host=localhost;dbname=test', 'root', '');
$pdo->exec('CREATE TABLE articles (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255),
content TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
)');
echo "Таблица articles с автообновлением updated_at.";
Таблица articles с автообновлением updated_at.
Примечание: ON UPDATE CURRENT_TIMESTAMP работает только в MySQL. В других СУБД потребуется триггер.