Разработка на PHP: Как реализовать метод trySendTelegramMessageToAdmin для мгновенного оповещения о критических ошибках базы данных?

Реализация метода `trySendTelegramMessageToAdmin` в PHP позволяет мгновенно уведомлять администратора о критических ошибках базы данных через Telegram Bot API. Рассмотрим полноценную реализацию с обработкой исключений и защитой от рекурсивных вызовов.

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

Для начала необходимо создать класс-обёртку, который будет отвечать за отправку сообщений:

php
class TelegramNotifier
{
private string $botToken;
private string $chatId;
private bool $isSending = false;

public function __construct(string $botToken, string $chatId)
{
$this->botToken = $botToken;
$this->chatId = $chatId;
}

public function trySendTelegramMessageToAdmin(string $message): bool
{
if ($this->isSending) {
return false; // Защита от рекурсии
}

$this->isSending = true;

try {
$url = sprintf(
‘https://api.telegram.org/bot%s/sendMessage’,
$this->botToken
);

$payload = json_encode([
‘chat_id’ => $this->chatId,
‘text’ => $message,
‘parse_mode’ => ‘HTML’,
]);

$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $payload,
CURLOPT_HTTPHEADER => [‘Content-Type: application/json’],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 5,
CURLOPT_CONNECTTIMEOUT => 3,
]);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

return $httpCode === 200;
} catch (Throwable $e) {
error_log(‘TelegramNotifier error: ‘ . $e->getMessage());
return false;
} finally {
$this->isSending = false;
}
}
}

## Интеграция с обработчиком ошибок БД

Для перехвата критических ошибок базы данных создайте класс-обработчик:

php
class DatabaseErrorHandler
{
private TelegramNotifier $notifier;

public function __construct(TelegramNotifier $notifier)
{
$this->notifier = $notifier;
}

public function handleCriticalDbError(Throwable $e, string $query = »): void
{
$message = sprintf(
«🚨 КРИТИЧЕСКАЯ ОШИБКА БД
. «Время: %sn»
. «Ошибка: %sn»
. «Файл: %s:%dn»
. «Запрос: %s«,
date(‘Y-m-d H:i:s’),
htmlspecialchars($e->getMessage()),
$e->getFile(),
$e->getLine(),
htmlspecialchars(mb_substr($query, 0, 200))
);

$this->notifier->trySendTelegramMessageToAdmin($message);
}
}

## Ключевые особенности реализации

1. **Флаг `$isSending`** — предотвращает рекурсивные вызовы, если сам Telegram-запрос вызовет ошибку.
2. **Таймаут cURL** — ограничение в 5 секунд гарантирует, что уведомление не заблокирует основной поток приложения.
3. **Блок `try/catch/finally`** — метод никогда не выбрасывает исключение наружу, что критично для обработчика ошибок.
4. **HTML-форматирование** — использование `parse_mode: HTML` делает сообщения читаемыми в Telegram.
5. **Логирование в `error_log`** — если Telegram недоступен, ошибка всё равно фиксируется.

## Настройка и запуск

php
$notifier = new TelegramNotifier(
botToken: getenv(‘TELEGRAM_BOT_TOKEN’),
chatId: getenv(‘TELEGRAM_ADMIN_CHAT_ID’)
);

$dbErrorHandler = new DatabaseErrorHandler($notifier);

try {
$pdo->exec($criticalQuery);
} catch (PDOException $e) {
$dbErrorHandler->handleCriticalDbError($e, $criticalQuery);
throw $e; // Пробрасываем дальше при необходимости
}

Токен бота получается через @BotFather в Telegram, а `chat_id` — через запрос к `getUpdates` API после отправки любого сообщения боту. Храните чувствительные данные в переменных окружения, а не в коде.


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

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