Database & Architecture
Thème :
Junior
1 vues ·11/12 leçonsImplémentation de l’Active Record
L’Active Record encapsule les lignes de la base de données dans des objets qui gèrent leur propre persistance.
Classe Active Record de Base
<?php
abstract class ActiveRecord {
protected static string $table = '';
protected static string $primaryKey = 'id';
protected static array $fillable = [];
protected array $attributes = [];
protected array $original = [];
protected bool $exists = false;
protected static ?PDO $pdo = null;
public static function setConnection(PDO $pdo): void {
static::$pdo = $pdo;
}
public function __get(string $name): mixed {
return $this->attributes[$name] ?? null;
}
public function __set(string $name, mixed $value): void {
if (in_array($name, static::$fillable, true)) {
$this->attributes[$name] = $value;
}
}
public function __isset(string $name): bool {
return isset($this->attributes[$name]);
}
public static function find(int $id): ?static {
$table = static::$table;
$pk = static::$primaryKey;
$stmt = static::$pdo->prepare("SELECT * FROM $table WHERE $pk = :id");
$stmt->execute(['id' => $id]);
$row = $stmt->fetch();
if (!$row) {
return null;
}
return static::hydrate($row);
}
protected static function hydrate(array $row): static {
$instance = new static();
$instance->attributes = $row;
$instance->original = $row;
$instance->exists = true;
return $instance;
}
public function save(): bool {
if ($this->exists) {
return $this->update();
}
return $this->insert();
}
protected function insert(): bool {
$table = static::$table;
$columns = array_keys($this->attributes);
$placeholders = array_map(fn($c) => ":$c", $columns);
$sql = sprintf(
'INSERT INTO %s (%s) VALUES (%s)',
$table,
implode(', ', $columns),
implode(', ', $placeholders)
);
$stmt = static::$pdo->prepare($sql);
$result = $stmt->execute($this->attributes);
if ($result) {
$this->attributes[static::$primaryKey] = (int) static::$pdo->lastInsertId();
$this->exists = true;
$this->original = $this->attributes;
}
return $result;
}
protected function update(): bool {
$dirty = $this->getDirty();
if (empty($dirty)) {
return true;
}
$table = static::$table;
$pk = static::$primaryKey;
$sets = array_map(fn($c) => "$c = :$c", array_keys($dirty));
$sql = sprintf(
'UPDATE %s SET %s WHERE %s = :pk_value',
$table,
implode(', ', $sets),
$pk
);
$params = $dirty;
$params['pk_value'] = $this->attributes[$pk];
$stmt = static::$pdo->prepare($sql);
$result = $stmt->execute($params);
if ($result) {
$this->original = $this->attributes;
}
return $result;
}
protected function getDirty(): array {
return array_diff_assoc($this->attributes, $this->original);
}
public function delete(): bool {
$table = static::$table;
$pk = static::$primaryKey;
$stmt = static::$pdo->prepare("DELETE FROM $table WHERE $pk = :id");
return $stmt->execute(['id' => $this->attributes[$pk]]);
}
}
📘 Cette leçon fait partie du cours PHP & Bases de Données Relationnelles sur la plateforme d’apprentissage RostoDev.
Prêt à passer à la suite ?
Vous avez terminé cette leçon sur Implémentation de l'Active Record. Continuez votre apprentissage avec la prochaine leçon ou explorez d'autres formations.