Implementare un ORM di base per PostgreSQL in PHP

Un ORM (Object-Relational Mapper) permette di interagire con un database utilizzando oggetti PHP invece di scrivere query SQL manualmente. In questo articolo, vedremo come costruire un ORM di base per PostgreSQL in PHP utilizzando PDO.

1. Connessione al database

Cominciamo creando una classe per gestire la connessione al database PostgreSQL:


class Database {
    private static ?PDO $pdo = null;

    public static function connect(string $dsn, string $user, string $pass): void {
        if (self::$pdo === null) {
            self::$pdo = new PDO($dsn, $user, $pass, [
                PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
            ]);
        }
    }

    public static function getConnection(): PDO {
        if (self::$pdo === null) {
            throw new RuntimeException("Database non connesso");
        }
        return self::$pdo;
    }
}

2. La classe base del modello

Questa è la classe astratta da cui erediteranno i modelli. Contiene i metodi per il salvataggio e il caricamento dei dati.


abstract class Model {
    protected static string $table = '';
    protected static string $primaryKey = 'id';

    public function save(): void {
        $props = get_object_vars($this);
        $fields = array_keys($props);
        $placeholders = array_map(fn($f) => ':' . $f, $fields);

        $sql = sprintf(
            "INSERT INTO %s (%s) VALUES (%s) ON CONFLICT (%s) DO UPDATE SET %s",
            static::$table,
            implode(', ', $fields),
            implode(', ', $placeholders),
            static::$primaryKey,
            implode(', ', array_map(fn($f) => "$f = EXCLUDED.$f", $fields))
        );

        $stmt = Database::getConnection()->prepare($sql);
        $stmt->execute($props);
    }

    public static function find($id): ?static {
        $sql = sprintf("SELECT * FROM %s WHERE %s = :id LIMIT 1", static::$table, static::$primaryKey);
        $stmt = Database::getConnection()->prepare($sql);
        $stmt->execute(['id' => $id]);

        $data = $stmt->fetch(PDO::FETCH_ASSOC);
        if ($data) {
            $obj = new static();
            foreach ($data as $key => $value) {
                $obj->$key = $value;
            }
            return $obj;
        }
        return null;
    }
}

3. Esempio di modello

Ora creiamo un modello che rappresenta una tabella chiamata users.


class User extends Model {
    protected static string $table = 'users';
    protected static string $primaryKey = 'id';

    public int $id;
    public string $name;
    public string $email;
}

4. Utilizzo

Ecco come usare l’ORM per inserire o recuperare un utente:


// Connessione
Database::connect('pgsql:host=localhost;dbname=test', 'username', 'password');

// Inserimento o aggiornamento
$user = new User();
$user->id = 1;
$user->name = 'Mario Rossi';
$user->email = 'mario@example.com';
$user->save();

// Recupero
$user = User::find(1);
echo $user->name;

Conclusione

Abbiamo implementato un semplice ORM in PHP che consente di salvare e recuperare oggetti da PostgreSQL. Per progetti più complessi, consigliamo l’uso di ORM completi come Eloquent o Doctrine, ma questo esempio è utile per comprendere i principi di base.

Torna su