Разработка на PHP: Как правильно реализовать обновление времени последней активности пользователя (last_activity) через PDO::prepare?

Обновление времени последней активности пользователя (поле `last_activity`) — стандартная задача при разработке веб-приложений на PHP. Правильная реализация через `PDO::prepare` обеспечивает безопасность, защиту от SQL-инъекций и производительность.

## Базовая реализация

Первым делом необходимо установить PDO-соединение с базой данных:

php
$dsn = ‘mysql:host=localhost;dbname=mydb;charset=utf8mb4’;
$pdo = new PDO($dsn, ‘username’, ‘password’, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
]);

Затем выполняем обновление `last_activity`:

php
function updateLastActivity(PDO $pdo, int $userId): bool {
$sql = ‘UPDATE users SET last_activity = NOW() WHERE id = :user_id’;
$stmt = $pdo->prepare($sql);
$stmt->bindValue(‘:user_id’, $userId, PDO::PARAM_INT);
return $stmt->execute();
}

## Почему важно использовать PDO::prepare

— **Защита от SQL-инъекций**: параметризованные запросы не позволяют злоумышленнику подставить вредоносный SQL-код.
— **Повторное использование**: подготовленный запрос можно выполнять многократно с разными параметрами без повторной компиляции.
— **Читаемость**: код становится чище и понятнее.

## Хранение времени: NOW() vs PHP

Можно использовать как серверное время MySQL (`NOW()`), так и время из PHP:

php
// Через PHP
$now = date(‘Y-m-d H:i:s’);
$sql = ‘UPDATE users SET last_activity = :now WHERE id = :user_id’;
$stmt = $pdo->prepare($sql);
$stmt->bindValue(‘:now’, $now, PDO::PARAM_STR);
$stmt->bindValue(‘:user_id’, $userId, PDO::PARAM_INT);
$stmt->execute();

Рекомендуется использовать `NOW()` на стороне MySQL, чтобы избежать расхождений при разных часовых поясах серверов.

## Оптимизация: не обновлять слишком часто

Если `last_activity` обновляется при каждом запросе, это создаёт нагрузку на БД. Оптимальный подход — обновлять не чаще одного раза в несколько минут:

php
function updateLastActivityThrottled(PDO $pdo, int $userId, int $intervalSeconds = 300): bool {
$sql = ‘UPDATE users SET last_activity = NOW()
WHERE id = :user_id
AND (last_activity IS NULL OR last_activity prepare($sql);
$stmt->bindValue(‘:user_id’, $userId, PDO::PARAM_INT);
$stmt->bindValue(‘:interval’, $intervalSeconds, PDO::PARAM_INT);
return $stmt->execute();
}

## Индексирование поля last_activity

Если вы часто делаете выборки по полю `last_activity` (например, для поиска онлайн-пользователей), добавьте индекс:

sql
ALTER TABLE users ADD INDEX idx_last_activity (last_activity);

## Обработка ошибок

Всегда оборачивайте запросы в блок `try-catch`:

php
try {
updateLastActivity($pdo, $userId);
} catch (PDOException $e) {
error_log(‘Ошибка обновления last_activity: ‘ . $e->getMessage());
}

## Итог

Использование `PDO::prepare` для обновления `last_activity` — это безопасный, производительный и профессиональный подход. Применяйте параметризованные запросы, контролируйте частоту обновлений и не забывайте про индексы.


Задайте вопрос нейросети

Не нашли ответ? Спросите ИИ — он подготовит развёрнутую статью.