Вывод содержимого через ID в PHP

Раздел: Управление контентом -> Контент

Обзор методов извлечения данных по id

Как получить запись из таблицы по id с использованием PDO?

PDO (PHP Data Objects) – интерфейс для безопасного доступа к базам данных. Подготовленные запросы исключают SQL-инъекции.

  1. Создать соединение с БД через DSN.
  2. Подготовить запрос с именованным плейсхолдером :id.
  3. Выполнить запрос, передав массив с привязкой.
  4. Извлечь запись и отобразить, экранируя вывод.
<?php
try {
    $pdo = new PDO('mysql:host=localhost;dbname=site_db;charset=utf8', 'user', 'pass');
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $id = isset($_GET['id']) ? (int)$_GET['id'] : 0;
    $stmt = $pdo->prepare('SELECT title, body FROM articles WHERE id = :id');
    $stmt->execute([':id' => $id]);
    $article = $stmt->fetch(PDO::FETCH_ASSOC);
    if ($article) {
        echo '<h2>' . htmlspecialchars($article['title'], ENT_QUOTES) . '</h2>';
        echo '<div>' . htmlspecialchars($article['body'], ENT_QUOTES) . '</div>';
    } else {
        echo 'Запись не найдена.';
    }
} catch (PDOException $e) {
    echo 'Ошибка соединения или запроса: ' . $e->getMessage();
}
?>

Article php page (статья на php)

(на экране – заголовок и тело статьи или сообщение об отсутствии)

View content php id (просмотр контента php по id)

Типичные ошибки и их решения:

  • ID не передан или содержит нечисловые символы – использовать приведение к int или фильтр FILTER_VALIDATE_INT.
  • PDOException не ловится – проверить настройки ATTR_ERRMODE.
  • Вывод без экранирования приводит к XSS – применять htmlspecialchars с кодировкой UTF-8.

Как выполнить выборку по id через MySQLi в объектно-ориентированном стиле?

MySQLi (MySQL Improved) поддерживает подготовленные запросы и предоставляет объектный интерфейс.

<?php
$mysqli = new mysqli('localhost', 'user', 'pass', 'site_db');
if ($mysqli->connect_error) {
    die('Ошибка подключения: ' . $mysqli->connect_error);
}
$id = intval($_GET['id'] ?? 0);
$stmt = $mysqli->prepare('SELECT * FROM articles WHERE id = ?');
$stmt->bind_param('i', $id);
$stmt->execute();
$result = $stmt->get_result();
$row = $result->fetch_assoc();
if ($row) {
    echo htmlspecialchars($row['title']);
} else {
    echo 'Материал отсутствует.';
}
$stmt->close();
$mysqli->close();
?>

Index php view article (индекс php просмотр статьи)

Возможные проблемы:

  • Ошибка bind_param из-за неправильного типа (i – integer, s – string).
  • Отсутствие get_result() без установки mysqlnd – альтернатива bind_result.
  • Утечка памяти при незакрытых запросах.

Как вывести данные по id с помощью процедурного MySQLi?

Процедурный стиль MySQLi аналогичен по функциональности, но использует функции вместо методов.

<?php
$link = mysqli_connect('localhost', 'user', 'pass', 'site_db');
if (!$link) {
    die('Ошибка соединения: ' . mysqli_connect_error());
}
$id = (int)$_GET['id'];
$stmt = mysqli_prepare($link, 'SELECT body FROM pages WHERE id = ?');
mysqli_stmt_bind_param($stmt, 'i', $id);
mysqli_stmt_execute($stmt);
mysqli_stmt_bind_result($stmt, $body);
if (mysqli_stmt_fetch($stmt)) {
    echo htmlspecialchars($body);
} else {
    echo 'Страница не найдена.';
}
mysqli_stmt_close($stmt);
mysqli_close($link);
?>

Частые ошибки:

  • Забывают вызвать mysqli_stmt_bind_result после execute.
  • Не проверяют наличие записи перед fetch.

Как организовать выборку по id с помощью простой ORM (на примере RedBeanPHP)?

ORM позволяет работать с базой данных через объекты, скрывая SQL. RedBeanPHP требует минимальной настройки.

<?php
require 'rb.php';
R::setup('mysql:host=localhost;dbname=site_db', 'user', 'pass');
$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT);
if ($id) {
    $article = R::load('articles', $id);
    if ($article->id) {
        echo '<h2>' . htmlspecialchars($article->title) . '</h2>';
        echo $article->body;
    } else {
        echo 'Статья не существует.';
    }
} else {
    echo 'Некорректный идентификатор.';
}
?>

Особенности:

  • RedBeanPHP автоматически определяет структуру таблицы, но может создавать лишние поля.
  • При отсутствии записи R::load возвращает пустой объект с id=0 – требуется проверка.

Развёрнутые примеры с кодом и результатами

Ниже представлены варианты вывода данных по id с дополнительными обработками.

Пример
<?php
// Пример 1: PDO с фильтрацией и пагинацией по предыдущему/следующему id
$pdo = new PDO('mysql:host=localhost;dbname=blog', 'root', '');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT, ['options' => ['min_range' => 1]]);
if (!$id) {
    die('Неверный ID.');
}

// Выборка записи
$stmt = $pdo->prepare('SELECT id, title, content, created_at FROM posts WHERE id = ?');
$stmt->execute([$id]);
$post = $stmt->fetch(PDO::FETCH_OBJ);

if (!$post) {
    http_response_code(404);
    echo 'Запись не найдена.';
    exit;
}

// Ссылки на соседние записи
$prev = $pdo->query("SELECT id FROM posts WHERE id < $id ORDER BY id DESC LIMIT 1")->fetchColumn();
$next = $pdo->query("SELECT id FROM posts WHERE id > $id ORDER BY id ASC LIMIT 1")->fetchColumn();

?>

<article>
    <h2><?= htmlspecialchars($post->title, ENT_QUOTES) ?></h2>
    <time><?= $post->created_at ?></time>
    <div><?= nl2br(htmlspecialchars($post->content)) ?></div>
</article>

<nav>
    <?php if ($prev): ?>
        <a href="?id=<?= $prev ?>">Предыдущая</a>
    <?php endif; ?>
    <?php if ($next): ?>
        <a href="?id=<?= $next ?>">Следующая</a>
    <?php endif; ?>
</nav>
(На странице отображается статья со ссылками на соседние записи. При отсутствии предыдущей или следующей записи ссылки скрываются.)
Пример
<?php
// Пример 2: MySQLi с извлечением в JSON для AJAX
header('Content-Type: application/json; charset=utf-8');

$mysqli = new mysqli('localhost', 'user', 'pass', 'api_db');
$id = $_GET['id'] ?? 0;

$stmt = $mysqli->prepare('SELECT id, name, description FROM items WHERE id = ?');
$stmt->bind_param('i', $id);
$stmt->execute();
$result = $stmt->get_result();
$item = $result->fetch_assoc();

if ($item) {
    echo json_encode($item, JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR);
} else {
    http_response_code(404);
    echo json_encode(['error' => 'Not found']);
}
?>
{
  "id": 5,
  "name": "Товар",
  "description": "Описание товара"
}
(или {"error":"Not found"} при отсутствии)
Пример
<?php
// Пример 3: Использование filter_var для валидации ID и защита от XSS
$id = filter_var($_GET['id'] ?? null, FILTER_VALIDATE_INT, [
    'options' => ['min_range' => 1, 'max_range' => 1000000],
    'flags' => FILTER_NULL_ON_FAILURE
]);

if ($id === null) {
    exit('Некорректный идентификатор.');
}

$pdo = new PDO(/* ... */);
$stmt = $pdo->prepare('SELECT * FROM news WHERE id = ?');
$stmt->execute([$id]);
$news = $stmt->fetch(PDO::FETCH_ASSOC);

if ($news) {
    echo '<div class="news-item">';
    echo '<h3>' . htmlspecialchars($news['title'], ENT_QUOTES) . '</h3>';
    echo '<p>' . htmlspecialchars($news['summary'], ENT_QUOTES) . '</p>';
    echo '<div>' . htmlspecialchars($news['full_text'], ENT_QUOTES) . '</div>';
    echo '</div>';
} else {
    echo 'Новость с таким ID не найдена.';
}
(Выводится блок новости с заголовком, кратким содержанием и полным текстом. Весь HTML экранирован, скрипты не выполняются.)
Пример
<?php
// Пример 4: Выборка по ID с использованием одного запроса для нескольких ID (IN)
$ids = [1, 3, 5]; // например, из URL: $_GET['ids'] = '1,3,5'
$ids = array_filter(array_map('intval', explode(',', $ids)), fn($v) => $v > 0);

if (empty($ids)) {
    exit('Нет валидных ID.');
}

$placeholders = implode(',', array_fill(0, count($ids), '?'));
$stmt = $pdo->prepare("SELECT id, name FROM categories WHERE id IN ($placeholders)");
$stmt->execute($ids);
$categories = $stmt->fetchAll(PDO::FETCH_KEY_PAIR); // id => name

foreach ($categories as $id => $name) {
    echo "ID: $id, Название: " . htmlspecialchars($name) . "<br>";
}
ID: 1, Название: Новости
ID: 3, Название: Статьи
ID: 5, Название: Обзоры

Просмотр контента PHP по ID - comments

En
View content php id (php)