Initial commit
This commit is contained in:
99
backend/app/Core/Database.php
Normal file
99
backend/app/Core/Database.php
Normal file
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
namespace App\Core;
|
||||
|
||||
use PDO;
|
||||
use PDOException;
|
||||
|
||||
/**
|
||||
* PDO Database wrapper using Singleton pattern.
|
||||
*/
|
||||
class Database
|
||||
{
|
||||
private static ?PDO $instance = null;
|
||||
|
||||
/**
|
||||
* Get active PDO database instance
|
||||
*
|
||||
* @return PDO
|
||||
* @throws PDOException
|
||||
*/
|
||||
public static function getConnection(): PDO
|
||||
{
|
||||
if (self::$instance === null) {
|
||||
$host = getenv('DB_HOST') ?: '127.0.0.1';
|
||||
$port = getenv('DB_PORT') ?: '3306';
|
||||
$dbName = getenv('DB_DATABASE') ?: 'nabeh_master';
|
||||
$username = getenv('DB_USERNAME') ?: 'root';
|
||||
$password = getenv('DB_PASSWORD') ?: '';
|
||||
|
||||
$dsn = "mysql:host={$host};port={$port};dbname={$dbName};charset=utf8mb4";
|
||||
|
||||
$options = [
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
PDO::ATTR_EMULATE_PREPARES => false,
|
||||
];
|
||||
|
||||
try {
|
||||
self::$instance = new PDO($dsn, $username, $password, $options);
|
||||
} catch (PDOException $e) {
|
||||
// Log the exact error internally but hide sensitive DSN on production
|
||||
error_log("Database Connection Error: " . $e->getMessage());
|
||||
throw new PDOException("Could not connect to the database. Check database settings.");
|
||||
}
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shorthand execute statement with parameters
|
||||
*
|
||||
* @param string $sql
|
||||
* @param array $params
|
||||
* @return \PDOStatement
|
||||
*/
|
||||
public static function query(string $sql, array $params = []): \PDOStatement
|
||||
{
|
||||
$pdo = self::getConnection();
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$stmt->execute($params);
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve all matching records
|
||||
*/
|
||||
public static function select(string $sql, array $params = []): array
|
||||
{
|
||||
return self::query($sql, $params)->fetchAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve single matching record
|
||||
*/
|
||||
public static function selectOne(string $sql, array $params = [])
|
||||
{
|
||||
return self::query($sql, $params)->fetch() ?: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert record and return last inserted ID
|
||||
*/
|
||||
public static function insert(string $sql, array $params = []): string
|
||||
{
|
||||
$pdo = self::getConnection();
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$stmt->execute($params);
|
||||
return $pdo->lastInsertId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute generic non-query SQL (Update/Delete) and return affected rows
|
||||
*/
|
||||
public static function execute(string $sql, array $params = []): int
|
||||
{
|
||||
return self::query($sql, $params)->rowCount();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user