I know you frown up double catch but wouldn’t the following be ok?
class ErrorHandler
{
public function handlePDOException(PDOException $e)
{
error_log('PDO Error: ' . $e->getMessage());
echo 'An error occurred while connecting to the database.';
}
public function handleGeneralException(Exception $e)
{
error_log('General Error: ' . $e->getMessage());
echo 'An error occurred.';
}
}
class MyClass
{
private ErrorHandler $errorHandler;
public function __construct(ErrorHandler $errorHandler)
{
$this->errorHandler = $errorHandler;
}
public function performAction()
{
try {
// Some code that may throw exceptions
} catch (PDOException $e) {
$this->errorHandler->handlePDOException($e);
} catch (Exception $e) {
$this->errorHandler->handleGeneralException($e);
}
}
}
I fix the method and added to class
```class LoginRepository {
private Database $database;
private string $table = 'admins'; // Replace with your actual table name
public function __construct(Database $database)
{
$this->database = $database;
}
public function verify_credentials($username, $password): bool
{
$sql = "SELECT id, password FROM " . $this->table . " WHERE username =:username LIMIT 1";
$user = $this->retrieve_credentials($sql, $username);
if ($user && password_verify($password, $user['password'])) {
session_regenerate_id(); // prevent session fixation attacks
$_SESSION['user_id'] = $user['id'];
return true;
}
return false;
}
protected function retrieve_credentials(string $sql, string $username): ?array
{
$pdo = $this->database->getConnection();
$stmt = $pdo->prepare($sql);
$stmt->execute([ 'username' => $username]);
$result = $stmt->fetch(PDO::FETCH_ASSOC);
return $result !== false ? $result : null;
}
public function store_token_in_database($user_id, $token) {
$pdo = $this->database->getConnection();
$sql = "UPDATE ". $this->table . " SET token=:token WHERE id=:id";
$stmt= $pdo->prepare($sql);
$stmt->execute(['token' => $token, 'id' => $user_id]);
return true;
}
}
This is how I use it in the php main file
/ Verify the username and password
if ($loginRepository->verify_credentials($username, $password)) {
// Generate a unique token
$token = bin2hex(random_bytes(32));
// Store the token in the user's database record (or other persistent storage mechanism)
$loginRepository->store_token_in_database($_SESSION['user_id'], $token);
// Set a cookie with the token and a 6-month expiration time
setcookie('login_token', $token, [
'expires' => strtotime('+6 months'),
'path' => '/',
'domain' => 'www.phototechguru.com',
'secure' => true,
'httponly' => true,
'samesite' => 'Lax'
]);
// Store the token in the user's session
$_SESSION['login_token'] = $token;
//echo 'It works!' . $token . "<br>";
// Redirect the user to the dashboard or home page
//header('Location: dashboard.php');
//exit;
} else {
// Invalid username or password
$error = 'Invalid username or password';
}
So I could something like the following doing away with the getConnection method?
namespace FanOfLEGO;
use PDO;
use PDOException;
class Database extends PDO
{
private static ?Database $_instance = null;
protected static function getInstance(): Database
{
if (!self::$_instance) {
self::$_instance = new self();
}
return self::$_instance;
}
public static function pdo(): PDO
{
return static::getInstance();
}
private function __construct()
{
$dsn = 'mysql:host=' . DATABASE_HOST . ';dbname=' . DATABASE_NAME . ';charset=utf8mb4';
$options = [
PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
];
try {
parent::__construct($dsn, DATABASE_USERNAME, DATABASE_PASSWORD, $options);
} catch (PDOException $e) {
// Handle the exception as needed, for example, by logging the error
// and displaying a user-friendly error message
throw $e;
}
}
private function __clone()
{
// Empty clone magic method to prevent duplication
}
}```
and this as an example
```namespace FanOfLEGO;
use PDO;
class UserRepository
{
private Database $database;
public function __construct(Database $database)
{
$this->database = $database;
}
public function getUserById(int $id): ?array
{
$stmt = $this->database->prepare("SELECT * FROM users WHERE id = :id");
$stmt->execute(['id' => $id]);
$result = $stmt->fetch(PDO::FETCH_ASSOC);
return $result !== false ? $result : null;
}
// Add more methods to interact with the user table as needed
}