Wenn eine Anwendung mehrdeutige Daten erhält, versucht sie oft, diese einer der beiden Kategorien „gültig“ oder „ungültig“ zuzuordnen. Damit wird das Problem meist verborgen statt gelöst. Das kann bei Formularen, Integrationen oder Ergebnissen vorkommen, die ein automatisiertes System vorschlägt: Es fehlt Kontext, um den Datensatz sicher anzunehmen oder zu verwerfen. In solchen Fällen muss die menschliche Prüfung unsicherer Daten in PHP ein Domänenstatus mit expliziten Regeln sein – kein informelles Label und keine improvisierte Warteschlange.
Das Design muss vier Fragen beantworten: Was ist eingegangen, was wird vorgeschlagen, wer muss entscheiden und was geschieht danach? Werden diese Zuständigkeiten getrennt, lässt sich der Ablauf leichter betreiben, Fehler lassen sich korrigieren und es kann erklärt werden, warum Daten auf eine bestimmte Weise verarbeitet wurden.
Das Problem klassifizieren, bevor du Status einführst

Nicht alle Daten, die nicht weiterverarbeitet werden können, erfordern eine menschliche Prüfung. Unterscheide mindestens die folgenden Fälle:
- Ungültig: Die Daten verstoßen gegen eine überprüfbare Regel, etwa ein Format, das nicht interpretiert werden kann. Je nach Herkunft und Produkt müssen sie abgelehnt oder zur Korrektur zurückgegeben werden.
- Unvollständig: Ein erforderliches Feld fehlt. Es kann nötig sein, die fehlende Angabe anzufordern, den Entwurf aufzubewahren oder auf eine zusätzliche Quelle zu warten.
- Unsicher: Es gibt mehrere plausible Interpretationen, oder die Belege reichen nicht für eine automatische Entscheidung aus. Der Fall muss möglicherweise von einer Person bewertet werden.
Die Prüfung darf nicht zum allgemeinen Ziel für jeden Fehler werden. Verstößt ein Wert gegen eine eindeutige Einschränkung, verursacht seine Weiterleitung an eine Prüfwarteschlange nur zusätzliche Arbeit. Hängt die Entscheidung dagegen von Kontext oder Ermessen ab, ermöglicht ein prüfbarer Status, die Verarbeitung anzuhalten, ohne die Daten voreilig als richtig oder falsch einzustufen.
Es empfiehlt sich außerdem, diesen Ablauf von einer Importquarantäne zu unterscheiden. Eine Quarantäne isoliert üblicherweise Eingaben, die nicht in das System übernommen werden dürfen, etwa weil technische oder sicherheitsbezogene Prüfungen fehlgeschlagen sind. Bei einer Prüfung wird eine geschäftliche Mehrdeutigkeit geklärt. Ein Datensatz kann beide Mechanismen durchlaufen, doch ihre Ziele, Berechtigungen und Kriterien für den Abschluss sind nicht austauschbar.
Einen überschaubaren und expliziten Lebenszyklus definieren
Beginne mit den Status, die erforderlich sind, um den Prozess abzubilden, statt alle denkbaren zukünftigen Fälle aufzulisten. Ein einfacher Lebenszyklus könnte so aussehen:
pending_review: Wartet auf eine Entscheidung.confirmed: Eine Person bestätigt einen verwendbaren Wert.rejected: Die Person entscheidet, dass die Daten nicht verarbeitet werden sollen.reopenedoder ein neuer Eintrag zur Prüfung: Eine frühere Entscheidung wird erneut infrage gestellt.
Definiere zulässige Übergänge. Ein ausstehender Fall kann beispielsweise bestätigt oder abgelehnt werden; ein bereits abgeschlossener Fall kann nur unter autorisierten Bedingungen wieder geöffnet werden. Erlaube nicht, dass eine beliebige Anfrage den Status direkt auf einen beliebigen Wert setzt. Ein Übergang muss den Ausgangsstatus, den Zielstatus, den zulässigen Akteur und die zugehörigen Auswirkungen festlegen.
Speichere den Entscheidungsgrund und die Identität der verantwortlichen Person. Wird ein Datensatz abgelehnt, erfasse einen hilfreichen Grund und nicht nur einen booleschen Wert. Wird eine Interpretation bestätigt, halte fest, welcher Wert freigegeben wurde und – sofern zutreffend – welche Belege die Entscheidung stützten. Lege je nach Aktion fest, ob eine Begründung erforderlich ist, und vermeide unnötige personenbezogene Daten in Freitextnotizen.
Eingabe, Vorschlag und bestätigten Wert voneinander trennen
Ein robustes Design überschreibt die eingegangenen Daten nicht mit der Interpretation eines automatisierten Prozesses oder der Korrektur einer Person. Halte die folgenden Konzepte getrennt:
- Eingegangene Daten: die ursprüngliche Eingabe und ihre Herkunft, mit angemessenen Zugriffskontrollen und Aufbewahrungsregeln.
- Vorgeschlagene Interpretation: ein Vorschlag aus Regeln, einer Integration oder einem unterstützenden System, zusammen mit den für seine Bewertung erforderlichen Informationen.
- Bestätigter Wert: der Wert, den die Anwendung nach einer autorisierten Entscheidung verwendet.
Diese Trennung verhindert, dass ein Vorschlag versehentlich als Wahrheit behandelt wird, und ermöglicht es nachzuvollziehen, wie der aktuelle Wert zustande kam. Es ist nicht nötig, jedes Feld wahllos zu duplizieren: Bewahre die für Audits und Support erforderlichen Daten unter Beachtung der Aufbewahrungs- und Datenschutzrichtlinien auf. Enthält ein Vorschlag eine Bewertung oder eine automatisierte Erklärung, behandle sie als Kontext und nicht als Entscheidung.
Erfasse Änderungen als Ereignisse oder unveränderliche Verlaufseinträge für den normalen Anwendungsbetrieb: Fall-ID, Aktion, vorheriger und neuer Status, Akteur, Zeitpunkt und Begründung. Zusätzlich kann das Modell den aktuellen Status speichern, damit die Warteschlange einfach abgefragt werden kann. Eine Korrektur wird durch eine neue, mit dem Verlauf verknüpfte Entscheidung oder Wiedereröffnung dargestellt; das Löschen der vorherigen Entscheidung zerstört die Nachvollziehbarkeit.
Entscheidungen in der Domänenschicht implementieren
Kapsle Übergänge in PHP in einem Anwendungsdienst oder einer Domänenentität, statt darauf zu vertrauen, dass jeder Controller dieselben Regeln anwendet. Ein schematisches Beispiel:
final class ReviewDecisionService
{
public function confirm(ReviewCase $case, User $actor, string $value, string $reason): void
{
if (!$actor->canReview($case)) {
throw new DomainException('Zugriff nicht erlaubt');
}
if (!$case->isPending()) {
throw new DomainException('Der Fall ist nicht ausstehend');
}
$case->confirm($value, $actor->id(), $reason);
}
}
Das Fragment veranschaulicht, wo Regeln untergebracht werden können, und ist keine vollständige Implementierung. Prüfe außerdem Format und Grenzen des Werts, stelle sicher, dass der Akteur für den betreffenden Fall autorisiert ist, und erfasse die Entscheidung. Verwechsle Authentifizierung – wer der Benutzer ist – nicht mit Autorisierung – was er mit diesem Datensatz tun darf. Gibt es Rollen oder eine Funktionstrennung, bilde diese Einschränkungen als Produktregeln ab.
Müssen die Aktualisierung des Falls und das Schreiben des Verlaufs konsistent sein, speichere beides in einer Datenbanktransaktion. Löst die Entscheidung externe Auswirkungen aus, etwa einen Aufruf einer anderen API, solltest du nicht davon ausgehen, dass die lokale Transaktion auch dieses System abdeckt. Verwende einen zuverlässigen Zustellmechanismus, beispielsweise eine transaktionale Outbox, sofern es die Architektur erfordert, und entwirf die Verbraucher so, dass sie Wiederholungsversuche tolerieren.
Eine Warteschlange gestalten, die Entscheidungen unterstützt
Eine hilfreiche Warteschlange ermöglicht es, Fälle zu priorisieren und zu finden, ohne ihren Kontext zu verschleiern. Sie sollte relevante Filter – Status, Datum, Typ oder Zuweisung – enthalten und nur die Informationen anzeigen, die zum Verständnis des Falls erforderlich sind. Gibt es einen Vorschlag, muss deutlich sein, dass es sich um einen Vorschlag handelt. Zeige Herkunft, Prüfgrund und verfügbare Aktionen an und vermeide Bedienelemente für Aktionen, zu denen der Benutzer nicht berechtigt ist.
Eine Zuweisung kann doppelte Arbeit verringern, ersetzt aber weder die Autorisierung noch den Schutz vor gleichzeitigen Entscheidungen. Eine Person kann einen Fall öffnen, den eine andere Person erledigt, bevor die erste ihre Antwort abschickt. Damit eine veraltete Ansicht keine neuere Änderung überschreibt, solltest du optimistische Nebenläufigkeitskontrolle verwenden: Vergleiche beim Speichern eine Version oder einen Zeitstempel und lehne den veralteten Vorgang ab, damit der Benutzer den Fall neu lädt.
Benötigt der Prozess zeitlich begrenzte Reservierungen, lege deren Ablauf und die Folgen ihres Verfalls fest. Verwende keine dauerhafte Zuweisung als unbeabsichtigte Sperre. Erfasse relevante Aktionen, damit nachvollziehbar ist, wer den Fall geprüft hat, und damit Datensätze erkannt werden, die länger als betrieblich akzeptabel ausstehend bleiben.
Korrigieren und wieder öffnen, ohne die Vergangenheit zu löschen
Eine Entscheidung kann falsch sein oder sich ändern, weil neue Belege eingegangen sind. Lege fest, wer sie wieder öffnen darf, welche Begründung erforderlich ist und ob der bestätigte Wert während der erneuten Prüfung nicht mehr verfügbar ist. Die Antwort hängt davon ab, wie sich der Wert auf nachgelagerte Prozesse auswirkt; beispielsweise kann es nötig sein, weitere Aktionen anzuhalten, bereits eingetretene Auswirkungen aber nicht automatisch zu löschen.
Bewahre die vorherige Entscheidung im Verlauf auf und erstelle eine neue Version oder ein neues Prüfereignis. Erfordert die Korrektur der Daten eine Neuberechnung abhängiger Informationen, benenne diese Auswirkungen ausdrücklich und lege ein idempotentes Verfahren fest, um Duplikate zu vermeiden. Eine Statuskorrektur darf nicht vortäuschen, dass ein externer Vorgang bereits rückgängig gemacht wurde.
Regeln, Berechtigungen und nachgelagerte Auswirkungen testen

Die Tests müssen den gesamten Ablauf und seine Grenzfälle abdecken, nicht nur sicherstellen, dass das Formular gespeichert wird. Prüfe mindestens Folgendes:
- Ein ausstehender Fall akzeptiert die vorgesehenen Übergänge und weist alle anderen zurück.
- Akteure ohne Berechtigung können weder Entscheidungen treffen noch Fälle wieder öffnen oder eingeschränkte Daten einsehen.
- Jede Entscheidung bewahrt gemäß der festgelegten Richtlinie Akteur, Begründung sowie vorherige und neue Werte auf.
- Zwei gleichzeitige Änderungen dürfen nicht dazu führen, dass eine veraltete Entscheidung eine andere überschreibt.
- Ein Fehler beim Erfassen des Verlaufs darf nicht dazu führen, dass der Status ohne Nachvollziehbarkeit aktualisiert wird.
- Die Wiederholung einer nachgelagerten Aktion darf weder Vorgänge noch Benachrichtigungen duplizieren.
Prüfe anhand dieser Design-Checkliste, ob die Unsicherheit eine identifizierbare Ursache hat; ob ursprüngliche Daten, Vorschlag und bestätigter Wert voneinander getrennt sind; ob für jeden Übergang eine Berechtigung und eine Begründung festgelegt sind; ob die Warteschlange ausreichend Kontext bietet; und ob beim Wiederöffnen der Verlauf erhalten bleibt und die betrieblichen Auswirkungen definiert sind. Hängt einer dieser Punkte von informellen Konventionen ab, fehlt noch eine Systemregel.



