The constructor (__construct) is called automatically when an object is created. The destructor (__destruct) is called when the object is destroyed (goes out of scope, or when the script ends).
Use the constructor to initialise properties, open resources, or validate arguments.
Use the destructor to release resources like file handles or database connections.
<?php
class DatabaseConnection
{
private \PDO $pdo;
private static int $instanceCount = 0;
public function __construct(
private string $dsn,
private string $user,
private string $pass
) {
// Constructor body runs after property promotion
$this->pdo = new \PDO($this->dsn, $this->user, $this->pass, [
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
\PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,
]);
self::$instanceCount++;
echo "Connection opened. Total: " . self::$instanceCount . "
";
}
public function query(string $sql, array $params = []): array
{
$stmt = $this->pdo->prepare($sql);
$stmt->execute($params);
return $stmt->fetchAll();
}
public function __destruct()
{
// Called when object goes out of scope or script ends
self::$instanceCount--;
echo "Connection closed. Remaining: " . self::$instanceCount . "
";
// \PDO closes the connection when $this->pdo is garbage-collected
}
}
$db = new DatabaseConnection('mysql:host=localhost;dbname=shop', 'root', 'secret');
// ... use $db ...
// When $db goes out of scope, __destruct is called automatically
unset($db); // forces immediate destruction
Pro Tip
Tip: Destructors are not guaranteed to run at a specific time — the PHP garbage collector decides when to collect objects. Do not rely on __destruct for critical clean-up logic; use explicit close() / disconnect() methods called in finally blocks instead.