Doctrine-Grundlagen: Entities definieren
Doctrine-Grundlagen: Entities definieren
~16 Min. Lesezeit Zuletzt aktualisiert am 8. August 2026
Endlich bekommt unser Aufgaben-Manager eine ECHTE Datenbank. Doctrine ist Symfonys Standard-ORM (Object-Relational Mapper) – PHP-Klassen werden zu Datenbanktabellen, OHNE eine einzige Zeile SQL von Hand zu schreiben.
Doctrine installieren
composer require symfony/orm-pack
composer require --dev symfony/maker-bundleDie orm-pack-Recipe (Kapitel 6) richtet config/packages/doctrine.yaml und DATABASE_URL in .env automatisch ein – GENAU der Wert, den wir bereits in Kapitel 2 vorbereitet haben.
Die Project-Entity generieren
php bin/console make:entity Project
# Interaktiv abgefragt:
# name (string, 255, nullable: no)
# description (text, nullable: yes)
# createdAt (datetime_immutable, nullable: no)make:entity stellt interaktiv Fragen und generiert daraus die vollständige PHP-Klasse – ein bewusst geführter Prozess, den wir hier einmal manuell nachvollziehen, um zu verstehen, WAS dabei entsteht:
<?php
declare(strict_types=1);
namespace App\Entity;
use App\Repository\ProjectRepository;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: ProjectRepository::class)]
class Project
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\Column(length: 255)]
private string $name = '';
#[ORM\Column(type: 'text', nullable: true)]
private ?string $description = null;
#[ORM\Column]
private \DateTimeImmutable $createdAt;
public function __construct()
{
$this->createdAt = new \DateTimeImmutable();
}
public function getId(): ?int
{
return $this->id;
}
public function getName(): string
{
return $this->name;
}
public function setName(string $name): static
{
$this->name = $name;
return $this;
}
public function getDescription(): ?string
{
return $this->description;
}
public function setDescription(?string $description): static
{
$this->description = $description;
return $this;
}
public function getCreatedAt(): \DateTimeImmutable
{
return $this->createdAt;
}
}Die Attribute im Detail
#[ORM\Entity]– markiert die Klasse als Doctrine-Entity, also als "wird in der Datenbank gespeichert".#[ORM\Id]– dieses Feld ist der Primärschlüssel.#[ORM\GeneratedValue]– die Datenbank vergibt den Wert automatisch (AUTO_INCREMENT/SEQUENCE).#[ORM\Column]– dieses PHP-Property wird zu einer Datenbankspalte. Ohne explizite Optionen wird der Typ aus der PHP-Typdeklaration abgeleitet.
Das Fluent-Setter-Muster: return $this
setName() gibt $this zurück statt void – erlaubt VERKETTETE Aufrufe:
$projekt = (new Project())
->setName('Website-Relaunch')
->setDescription('Kompletter Redesign der Firmenwebsite');getId() hat KEINEN Setter – die ID wird AUSSCHLIESSLICH von der Datenbank vergeben, niemals manuell gesetzt. Der Rückgabetyp ?int (nullable) spiegelt wider, dass eine NEUE, noch nicht gespeicherte Entity noch KEINE ID hat.
Das Mapping validieren
php bin/console doctrine:schema:validateTipp: Nützlich NACH jeder manuellen Änderung an einer Entity, um sicherzustellen, dass Doctrines interne Metadaten (aus den Attributen abgeleitet) konsistent sind, BEVOR eine Migration erstellt wird (Kapitel 20).
Die restlichen Entities im Vorgriff
In den kommenden Kapiteln entstehen analog: User (Kapitel 26, mit Security-Interfaces), Task (Kapitel 22, mit Beziehung zu Project), Comment (Kapitel 22/23) – GENAU das Domänenmodell aus Kapitel 5.