PHP: визуализация таблиц – полное руководство
Основные подходы к отображению таблиц в PHP
Рекомендуемый способ: PDO с экранированием вывода
Как безопасно вывести таблицу из базы данных с помощью PDO?
Наиболее универсальный и защищённый способ отображения табличных данных в PHP использует расширение PDO. Оно поддерживает множество СУБД, а подготовленные запросы предотвращают SQL-инъекции.
// Подключение к базе данных MySQL через PDO
$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'user', 'password');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// Выполнение запроса
$stmt = $pdo->query('SELECT id, name, email FROM users');
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Начало таблицы
echo '';
echo 'ID Имя Email ';
echo '';
foreach ($rows as $row) {
echo '';
// Экранирование вывода для предотвращения XSS
echo '' . htmlspecialchars($row['id'], ENT_QUOTES, 'UTF-8') . ' ';
echo '' . htmlspecialchars($row['name'], ENT_QUOTES, 'UTF-8') . ' ';
echo '' . htmlspecialchars($row['email'], ENT_QUOTES, 'UTF-8') . ' ';
echo ' ';
}
echo '';
echo '
';
поиск данных php (поиск данных в php (общие методы))
Типичные проблемы:
- Отсутствие экранирования приводит к XSS-уязвимости. Решение: всегда использовать
htmlspecialchars(). - Ошибка соединения с БД. Решение: обернуть код в try-catch и выводить понятное сообщение.
- Некорректная кодировка. Решение: указать charset в DSN и в meta-теге HTML.
Использование MySQLi (объектно-ориентированный стиль)
Как вывести таблицу через MySQLi без PDO?
MySQLi позволяет работать только с MySQL, но также поддерживает подготовленные запросы. Пример вывода всех строк с помощью fetch_assoc().
$mysqli = new mysqli('localhost', 'user', 'password', 'test');
$mysqli->set_charset('utf8');
$result = $mysqli->query('SELECT id, name, email FROM users');
echo '';
echo 'ID Name Email ';
while ($row = $result->fetch_assoc()) {
echo '';
echo '' . htmlspecialchars($row['id']) . ' ';
echo '' . htmlspecialchars($row['name']) . ' ';
echo '' . htmlspecialchars($row['email']) . ' ';
echo ' ';
}
echo '
';
$result->free();
$mysqli->close();
View php table (php: отображение таблиц)
Частые ошибки:
- Использование устаревшего процедурного стиля. Рекомендуется объектно-ориентированный.
- Не закрытие соединения. Хотя PHP закрывает его автоматически, лучше делать это явно.
Вывод таблицы из двумерного массива (без БД)
Как отобразить данные, хранящиеся в виде массива PHP?
При работе с файлами, API или временными данными часто используется массив. Пример с вложенным циклом по строкам и столбцам.
$data = [
['name' => 'Иван', 'age' => 25],
['name' => 'Мария', 'age' => 30],
['name' => 'Пётр', 'age' => 28]
];
echo '';
// Заголовки на основе ключей первой строки
$headers = array_keys($data[0]);
echo '';
foreach ($headers as $header) {
echo '' . htmlspecialchars($header) . ' ';
}
echo ' ';
foreach ($data as $row) {
echo '';
foreach ($row as $value) {
echo '' . htmlspecialchars($value) . ' ';
}
echo ' ';
}
echo '
';
Index php collection (коллекции в php)
Если массив пуст, код вызовет ошибку. Перед выводом стоит проверять !empty($data).
Генерация таблицы с помощью шаблонизатора (Twig)
Как отделить логику от представления при выводе таблицы?
Шаблонизаторы, например Twig, позволяют вынести HTML-разметку в отдельные файлы. Это упрощает поддержку и повторное использование.
<?
// index.php
require_once 'vendor/autoload.php';
$loader = new \Twig\Loader\FilesystemLoader('templates');
$twig = new \Twig\Environment($loader);
$users = [['id' => 1, 'name' => 'Иван'], ['id' => 2, 'name' => 'Мария']];
echo $twig->render('table.html.twig', ['users' => $users]);
?>
{# templates/table.html.twig #}
<table>
<tr><th>ID</th><th>Name</th></tr>
{% for user in users %}
<tr>
<td>{{ user.id }}</td>
<td>{{ user.name|e }}</td>
</tr>
{% endfor %}
</table>
Php tables (работа с таблицами в php)
Требуется установка Twig через Composer. При неправильном пути к шаблонам возникает ошибка загрузки.
Использование ORM (например, Eloquent) для формирования таблицы
Как при работе с фреймворком вывести коллекцию моделей в таблицу?
В Laravel можно получить коллекцию объектов через модель и передать её в представление Blade. Blade автоматически экранирует вывод.
// В контроллере
$users = User::all();
return view('users.table', compact('users'));
// В Blade (users/table.blade.php)
<table>
<tr><th>ID</th><th>Name</th></tr>
@foreach($users as $user)
<tr>
<td>{{ $user->id }}</td>
<td>{{ $user->name }}</td>
</tr>
@endforeach
</table>
Данный подход применим только в контексте фреймворка.
Расширенные примеры отображения таблиц в PHP
Пример 1. Таблица с пагинацией через PDO
Как разбить большие наборы данных на страницы?
$page = isset($_GET['page']) ? (int)$_GET['page'] : 1;
$limit = 5;
$offset = ($page - 1) * $limit;
// Общее количество записей
$totalStmt = $pdo->query('SELECT COUNT(*) FROM users');
$total = $totalStmt->fetchColumn();
$pages = ceil($total / $limit);
$stmt = $pdo->prepare('SELECT id, name, email FROM users LIMIT :limit OFFSET :offset');
$stmt->bindValue(':limit', $limit, PDO::PARAM_INT);
$stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
$stmt->execute();
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Вывод таблицы (как в базовом примере)
echo '<table>...';
// Пагинация
for ($i = 1; $i <= $pages; $i++) {
echo '<a href="?page=' . $i . '">' . $i . '</a> ';
}
Страница 1: строки 1-5 Страница 2: строки 6-10 ... Ссылки для перехода между страницами.
Пример 2. Сортировка по столбцам (с защитой от инъекций)
Как разрешить пользователю сортировать таблицу по выбранному полю?
$allowedSort = ['id', 'name', 'email']; // белый список
$sort = isset($_GET['sort']) && in_array($_GET['sort'], $allowedSort) ? $_GET['sort'] : 'id';
$order = isset($_GET['order']) && $_GET['order'] === 'desc' ? 'DESC' : 'ASC';
$stmt = $pdo->query("SELECT id, name, email FROM users ORDER BY $sort $order");
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
echo '<table>';
echo '<tr><th><a href="?sort=id&order=' . ($sort === 'id' && $order === 'ASC' ? 'desc' : 'asc') . '">ID</a></th>...</tr>';
// ... вывод строк
Заголовки столбцов являются ссылками. При клике изменяется параметр sort и order. Названия столбцов защищены белым списком.
Пример 3. Группировка и итоговые значения
Как вывести таблицу с группировкой по категории и подсчётом суммы?
$stmt = $pdo->query('SELECT category, SUM(amount) as total FROM expenses GROUP BY category');
$data = $stmt->fetchAll(PDO::FETCH_ASSOC);
echo '<table><tr><th>Категория</th><th>Сумма</th></tr>';
$grandTotal = 0;
foreach ($data as $row) {
echo '<tr><td>' . htmlspecialchars($row['category']) . '</td><td>' . htmlspecialchars($row['total']) . '</td></tr>';
$grandTotal += $row['total'];
}
echo '<tr><td><b>Итого</b></td><td><b>' . htmlspecialchars($grandTotal) . '</b></td></tr>';
echo '</table>';
Таблица с категориями и итоговой строкой снизу.
Пример 4. Функция для рендеринга таблицы из ассоциативного массива
Как создать универсальную функцию, которая выводит любую таблицу?
function renderTable(array $data, array $headers = []): void {
if (empty($data)) {
echo '<p>Нет данных.</p>';
return;
}
$headers = $headers ?: array_keys(reset($data));
echo '<table class="table">';
echo '<thead><tr>';
foreach ($headers as $h) {
echo '<th>' . htmlspecialchars($h) . '</th>';
}
echo '</tr></thead><tbody>';
foreach ($data as $row) {
echo '<tr>';
foreach ($headers as $h) {
$value = $row[$h] ?? '';
echo '<td>' . htmlspecialchars($value) . '</td>';
}
echo '</tr>';
}
echo '</tbody></table>';
}
// Использование
$users = [['id'=>1,'name'=>'Alex'], ['id'=>2,'name'=>'Bob']];
renderTable($users);
Таблица с автоматическими заголовками на основе ключей элементов массива.
Пример 5. Вывод данных в формате JSON для динамической таблицы (AJAX)
Как подготовить PHP-скрипт, который отдаёт табличные данные для клиентского JavaScript?
// data.php
header('Content-Type: application/json');
$pdo = new PDO(...);
$stmt = $pdo->query('SELECT id, name FROM users');
$data = $stmt->fetchAll(PDO::FETCH_ASSOC);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
// Клиентский JS может загрузить эти данные и построить таблицу, например, с помощью DataTables.
JSON-ответ:
[{"id":1,"name":"Иван"},{"id":2,"name":"Мария"}]