Magento 2 Experten — Hyvä Theme, Tailwind CSS & SEO aus einer Hand ›

Event-Hooks mit Doctrine-Lifecycle-Events

Event-Hooks mit Doctrine-Lifecycle-Events

~13 Min. Lesezeit Zuletzt aktualisiert am 8. August 2026

State Processor (Kapitel 58) sind der BEVORZUGTE Weg für API-PLATFORM-spezifische Logik – für Logik, die UNABHÄNGIG davon greifen soll, WIE eine Entity gespeichert wird (auch außerhalb der API), sind Doctrine-Events die richtige Wahl.

Ein Beispiel: automatisches updatedAt

// Project.php - neues Feld
#[ORM\Column(nullable: true)]
#[Groups(['project:read'])]
private ?\DateTimeImmutable $updatedAt = null;

public function getUpdatedAt(): ?\DateTimeImmutable
{
    return $this->updatedAt;
}

public function setUpdatedAt(\DateTimeImmutable $updatedAt): static
{
    $this->updatedAt = $updatedAt;

    return $this;
}

Einen Event-Listener schreiben

api/src/EventListener/ProjectUpdatedAtListener.php
<?php

declare(strict_types=1);

namespace App\EventListener;

use App\Entity\Project;
use Doctrine\Bundle\DoctrineBundle\Attribute\AsEntityListener;
use Doctrine\ORM\Event\PrePersistEventArgs;
use Doctrine\ORM\Event\PreUpdateEventArgs;
use Doctrine\ORM\Events;

#[AsEntityListener(event: Events::prePersist, entity: Project::class)]
#[AsEntityListener(event: Events::preUpdate, entity: Project::class)]
final class ProjectUpdatedAtListener
{
    public function prePersist(Project $project, PrePersistEventArgs $args): void
    {
        $project->setUpdatedAt(new \DateTimeImmutable());
    }

    public function preUpdate(Project $project, PreUpdateEventArgs $args): void
    {
        $project->setUpdatedAt(new \DateTimeImmutable());
    }
}

#[AsEntityListener] registriert den Listener AUTOMATISCH bei Doctrine – prePersist feuert beim ERSTMALIGEN Speichern, preUpdate bei JEDER nachfolgenden Änderung, UNABHÄNGIG davon, ob über die API, eine Fixture oder eine Konsolen-Kommando ausgelöst.

Achtung: Der ENTSCHEIDENDE Unterschied zu Kapitel 58: ein Doctrine-Event feuert IMMER, auch bei einem bin/console-Skript OHNE jeden API-Bezug – ein State Processor greift NUR bei API-Requests. Für updatedAt ist das GEWÜNSCHTE Verhalten (IMMER aktuell, egal WIE gespeichert wird), für owner (Kapitel 54) WÄRE ein Doctrine-Event UNGEEIGNET, da Security::getUser() außerhalb eines HTTP-Requests NICHT verfügbar ist.

Wann Doctrine-Events statt Processor

MechanismusEinsatzbereich
State ProcessorLogik ist SPEZIFISCH für API-Requests (braucht z. B. den eingeloggten Nutzer, Request-Kontext)
Doctrine-EventLogik soll IMMER greifen, unabhängig VOM Auslöser (Datenintegrität, Audit-Timestamps)

Tipp: GENAU dieselben Doctrine-Events (prePersist, preUpdate, preRemove etc.) wurden BEREITS in der Symfony-Schulung behandelt (Kapitel 28) – das Wissen überträgt sich VOLLSTÄNDIG, NUR der Kontext (API statt klassischer Controller) ist neu.