connection = new mysqli( AppConfig::required('DB_HOST'), AppConfig::required('DB_USERNAME'), AppConfig::required('DB_PASSWORD'), AppConfig::required('DB_DATABASE'), AppConfig::integer('DB_PORT', 3306) ); $this->connection->set_charset('utf8mb4'); $this->connection->query("SET time_zone = '+00:00'"); } catch (Throwable $e) { error_log('Database initialization failed: ' . $e->getMessage()); throw new RuntimeException('Database connection failed', 0, $e); } } /** * Singleton instance getter */ public static function getInstance() { if (self::$instance === null) { self::$instance = new self(); } return self::$instance; } /** * Get connection */ public function getConnection() { return $this->connection; } /** * Prepare and execute query */ public function prepare($query) { return $this->connection->prepare($query); } /** * Escape string */ public function escape($string) { return $this->connection->real_escape_string($string); } /** * Close connection */ public function close() { if ($this->connection) { $this->connection->close(); } } /** * Begin transaction */ public function beginTransaction() { $this->connection->begin_transaction(); } /** * Commit transaction */ public function commit() { $this->connection->commit(); } /** * Rollback transaction */ public function rollback() { $this->connection->rollback(); } /** * Get last inserted ID */ public function getLastInsertId() { return $this->connection->insert_id; } /** * Get affected rows */ public function getAffectedRows() { return $this->connection->affected_rows; } } // Prevent cloning final class SingletonDatabase extends Database { private function __clone() {} public function __wakeup() { throw new LogicException('Database singleton cannot be unserialized'); } } ?>