126 lines
4.6 KiB
PHP
Executable File
126 lines
4.6 KiB
PHP
Executable File
<?php
|
|
require_once __DIR__ . '/../config/config.php';
|
|
|
|
// Establecer la zona horaria predeterminada
|
|
date_default_timezone_set('America/Mexico_City');
|
|
|
|
/**
|
|
* Clase para manejar la conexión a la base de datos con reconexión automática
|
|
*/
|
|
class DatabaseConnection {
|
|
private static $instance = null;
|
|
private $pdo = null;
|
|
private $config = [];
|
|
|
|
private function __construct() {
|
|
$this->config = [
|
|
'host' => $_ENV['DB_HOST'] ?? 'localhost',
|
|
'port' => $_ENV['DB_PORT'] ?? '3306',
|
|
'name' => $_ENV['DB_NAME'] ?? 'bot',
|
|
'user' => $_ENV['DB_USER'] ?? 'nickpons666',
|
|
'pass' => $_ENV['DB_PASS'] ?? 'MiPo6425@@',
|
|
'charset' => 'utf8mb4',
|
|
'timeout' => 30, // Tiempo de espera de conexión en segundos
|
|
'reconnect_attempts' => 3, // Número de intentos de reconexión
|
|
'reconnect_delay' => 1, // Tiempo de espera entre reconexiones en segundos
|
|
];
|
|
|
|
$this->connect();
|
|
}
|
|
|
|
public static function getInstance() {
|
|
if (self::$instance === null) {
|
|
self::$instance = new self();
|
|
}
|
|
return self::$instance;
|
|
}
|
|
|
|
public function getConnection() {
|
|
// Verificar si la conexión sigue activa
|
|
try {
|
|
$this->pdo->query('SELECT 1');
|
|
return $this->pdo;
|
|
} catch (PDOException $e) {
|
|
// Si la conexión se perdió, intentar reconectar
|
|
error_log("La conexión a la base de datos se perdió. Intentando reconectar...");
|
|
$this->connect();
|
|
return $this->pdo;
|
|
}
|
|
}
|
|
|
|
private function connect() {
|
|
$dsn = sprintf(
|
|
'mysql:host=%s;port=%s;dbname=%s;charset=%s',
|
|
$this->config['host'],
|
|
$this->config['port'],
|
|
$this->config['name'],
|
|
$this->config['charset']
|
|
);
|
|
|
|
$options = [
|
|
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
|
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
|
PDO::ATTR_EMULATE_PREPARES => false,
|
|
PDO::ATTR_TIMEOUT => $this->config['timeout'],
|
|
PDO::ATTR_PERSISTENT => false, // No usar conexiones persistentes para evitar problemas
|
|
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci"
|
|
];
|
|
|
|
$attempts = 0;
|
|
$lastException = null;
|
|
|
|
while ($attempts < $this->config['reconnect_attempts']) {
|
|
try {
|
|
$this->pdo = new PDO(
|
|
$dsn,
|
|
$this->config['user'],
|
|
$this->config['pass'],
|
|
$options
|
|
);
|
|
|
|
// Configuración adicional de la conexión
|
|
$this->pdo->exec("SET time_zone = '-06:00';");
|
|
$this->pdo->exec("SET SESSION wait_timeout=28800;"); // 8 horas
|
|
$this->pdo->exec("SET SESSION interactive_timeout=28800;"); // 8 horas
|
|
|
|
error_log("Conexión a la base de datos establecida correctamente.");
|
|
return;
|
|
|
|
} catch (PDOException $e) {
|
|
$lastException = $e;
|
|
$attempts++;
|
|
error_log(sprintf(
|
|
"Intento de conexión %d fallido: %s. Reintentando en %d segundos...",
|
|
$attempts,
|
|
$e->getMessage(),
|
|
$this->config['reconnect_delay']
|
|
));
|
|
|
|
if ($attempts < $this->config['reconnect_attempts']) {
|
|
sleep($this->config['reconnect_delay']);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Si llegamos aquí, todos los intentos fallaron
|
|
error_log("No se pudo establecer la conexión después de {$this->config['reconnect_attempts']} intentos.");
|
|
throw $lastException;
|
|
}
|
|
}
|
|
|
|
// Crear una instancia de la conexión
|
|
try {
|
|
$pdo = DatabaseConnection::getInstance()->getConnection();
|
|
} catch (PDOException $e) {
|
|
error_log("Error crítico de conexión a la base de datos: " . $e->getMessage());
|
|
// No usar die() aquí porque mata a los workers - dejar que el código maneje el error
|
|
// Para scripts web, el error se mostrará en el log y el script continuará
|
|
// Para workers, pueden manejar la excepción y reintentar
|
|
if (php_sapi_name() !== 'cli') {
|
|
// Solo para contexto web
|
|
die("Error de conexión a la base de datos. Por favor, inténtalo de nuevo más tarde.");
|
|
}
|
|
// Para CLI (workers), lanzar la excepción para que el worker la maneje
|
|
throw $e;
|
|
}
|
|
?>
|