Primer commit del sistema separado falta mejorar mucho
This commit is contained in:
126
Sistema_discord/db.php
Executable file
126
Sistema_discord/db.php
Executable file
@@ -0,0 +1,126 @@
|
||||
<?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;
|
||||
}
|
||||
?>
|
||||
Reference in New Issue
Block a user