SyntaxStudy
Sign Up
PHP Constructors & Destructors
PHP Beginner 7 min read

Constructors & Destructors

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 8.0 constructor property promotion reduces boilerplate significantly.
Example
<?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.