TYPO3 DataHandler: Warum direktes SQL in Extensions ein Risiko ist

Der DataHandler ist die zentrale API für sichere Datenbankoperationen in TYPO3. Ein Praxisleitfaden zu DataMap, CmdMap, Fehlerbehandlung, optionalen Transaktionen, SC_OPTIONS-Hooks und den v14-Breaking-Changes.

Auf einen Blick

  • Der DataHandler ist die einzige sichere Methode, um TCA-konfigurierte Tabellen in TYPO3 zu manipulieren – ohne ihn brechen Cache, Reference Index und Workspace-Kompatibilität.
  • Zwei Array-Strukturen steuern alles: DataMap ($data) für Create/Update und CmdMap ($cmd) für Copy/Move/Delete.
  • TYPO3 v14 entfernt mehrere öffentliche Properties und führt den neuen discard-Befehl für Workspace-Operationen ein.
  • Hooks wie processDatamap_afterDatabaseOperations ermöglichen es, auf jede Datenbankänderung zu reagieren – für Logging, Benachrichtigungen oder Synchronisation.
  • Warum der DataHandler für TCA-Tabellen Pflicht ist.
  • Wie die $data- und $cmd-Arrays aufgebaut sind.
  • Fehlerbehandlung, optionale DB-Transaktionen und CLI-Einsatz.
  • Hooks für Reaktionen auf Datenbankänderungen.
  • Alle v14-Breaking-Changes und Migrationsschritte.

Wer in einer TYPO3-Extension ein INSERT INTO tt_content absetzt, umgeht Cache-Invalidierung, Reference Index, Workspace-Versioning und die vom Core vorgesehenen DataHandler-Extension-Points (v. a. SC_OPTIONS-Hook-Klassen unter dem Legacy-Schlüssel t3lib/class.t3lib_tcemain.php, der auf \TYPO3\CMS\Core\DataHandling\DataHandler gemappt wird). Das funktioniert – bis es das nicht mehr tut. Der DataHandler ist die API, die diese Mechanismen zuverlässig orchestriert. Dieser Leitfaden ist mit dem Schwerpunkt TYPO3 v14 geschrieben; wo nötig, sind Übergänge aus v13 erwähnt.


Inhaltsverzeichnis  

Die goldene Regel

Warum direktes SQL Cache, Index und Workspaces sabotiert.

DataMap & CmdMap

Create, Update, Delete, Copy, Move – alles über zwei Arrays.

Ausführung & Fehler

Transaktionssicherheit, errorLog und substNEWwithIDs.

CLI & Scheduler

Admin-Kontext, Bootstrap und Symfony Commands.

Hooks

processDatamap, processCmdmap und praktische Listener.

Reference Index & Cache

Cache-Tags, referenceindex:update und clear_cacheCmd.

Workspace-Kompatibilität

Versionierte Records und der neue discard-Befehl (v14).

Häufige Fallstricke

Die vier Fehler, die in fast jeder Extension lauern.

v14 Breaking Changes

Entfernte Properties, ISO8601-Datumswerte und Migration.


Die goldene Regel: Kein rohes SQL für TCA-Tabellen  

Für pages, tt_content und jede andere TCA-konfigurierte Tabelle gilt: Verwenden Sie ausschließlich den DataHandler. Rohes SQL (INSERT, UPDATE, DELETE) umgeht sämtliche Integritätsmechanismen, die TYPO3 im Hintergrund ausführt.

FeatureDataHandlerRohes SQL
Reference Index (sys_refindex)
Cache-Invalidierung
Versionshistorie (sys_history)
Workspace-Kompatibilität
SC_OPTIONS-Hooks / dokumentierte Core-Events
FlexForm-Verarbeitung
MM-Relationen
Performance bei Bulk-ReadsStandardSchneller
Ausnahmen, in denen rohes SQL erlaubt ist
  • Custom-Logging-Tabellen ohne TCA-Konfiguration
  • Bulk-Analytics und Reporting (rein lesend)
  • Migrationsskripte mit explizitem Reference-Index-Rebuild danach
sys_file ist gesperrt

Seit TYPO3 v13.0.1 (und v12.4.11) blockiert der DataHandler Schreibzugriffe auf die sys_file-Tabelle. Zusätzliche Felder gehören in sys_file_metadata. Hintergrund ist das Security Advisory TYPO3-CORE-SA-2024-006.


Die zwei Kernstrukturen  

Alles, was der DataHandler tut, wird über zwei Arrays gesteuert: DataMap ($data) für Anlegen und Ändern, CmdMap ($cmd) für Verschieben, Kopieren und Löschen.

DataMap: Records erstellen und aktualisieren  

Syntax: $data[tabellenname][uid][feldname] = wert

Für neue Records verwenden Sie einen eindeutigen String mit dem Prefix NEW als UID:

TCA ist Voraussetzung

Der DataHandler verarbeitet nur Felder, die in $GLOBALS['TCA'] konfiguriert sind. Felder mit "type" => "none" oder ungültigen Typen werden ignoriert.

CmdMap: Records verschieben, kopieren, löschen  

Syntax: $cmd[tabellenname][uid][befehl] = wert

Soft-Delete wird automatisch verwendet, wenn $GLOBALS['TCA'][$table]['ctrl']['delete'] konfiguriert ist.


Ausführung, Fehlerbehandlung und neue UIDs  

Der DataHandler ist zustandsbehaftet. Verwenden Sie für jede Operation eine neue Instanz (in der Praxis typischerweise GeneralUtility::makeInstance(DataHandler::class)). Dieselbe Instanz sollten Sie nicht über mehrere unabhängige Schreibvorgänge hinweg wiederverwenden.

DataHandler-Ausführungsablauf: Von der Initialisierung bis zur UID-Auflösung

Basispattern  

substNEWwithIDs

Nach process_datamap() enthält $dataHandler->substNEWwithIDs die Zuordnung von NEW-Platzhaltern zu echten UIDs. Beispiel: $dataHandler->substNEWwithIDs['NEW_hero'] liefert die tatsächliche UID des angelegten Records.

Erweitert: Eigene DB-Transaktionen (mit Vorsicht)  

Die offizielle Dokumentation definiert keinen allgemeinen Transaktionsvertrag für den DataHandler. In Extensions genügt in der Regel zuerst die schlichte API (startprocess_datamap() / process_cmdmap()). Eigene beginTransaction() / commit() nur, wenn Sie mehrere Läufe oder eigene SQL-Schritte auf derselben Connection bewusst bündeln — und nach Prüfung von Seiteneffekten und DB-Connection.


CLI und Scheduler-Einsatz  

Im CLI-Kontext (Symfony Commands, Scheduler Tasks) existiert kein automatischer Backend-User. Sie müssen Bootstrap::initializeBackendAuthentication() aufrufen, bevor der DataHandler Schreiboperationen durchführt. Andernfalls erhalten Sie Fehler wie Attempt to modify table "pages" without permission.

Backend-User und Berechtigungen

Der _cli_-Backend-User benötigt die tatsächlich nötigen Rechte für Ihre Tabellen und Seiten. Nicht per Hand $GLOBALS['BE_USER']->user['admin'] = 1 setzen. Verwenden Sie einen echten BackendUserAuthentication-Datensatz mit passenden Rechten und übergeben Sie ihn optional als drittes Argument an start($data, $cmd, $backendUser). Berechtigungen prüfen Sie mit den üblichen TYPO3-Mechanismen — nicht durch ein gefaktes Admin-Flag.


Hooks: Auf Datenbankoperationen reagieren  

Der DataHandler bietet SC_OPTIONS-Hook-Klassen, über die Sie auf Datamap- und Cmdmap-Vorgänge reagieren können – für Logging, Benachrichtigungen, externe Synchronisation oder Validierung.

PSR-14 vs. SC_OPTIONS (TYPO3 v14)

Das Core liefert keine PSR-14-Events mit Namen wie BeforeRecordOperationEvent oder AfterDatabaseOperationsEvent für jeden Datamap-Schritt. Für Reaktionen nach DB-Schreiben sind die Hook-Klassen auf t3lib/class.t3lib_tcemain.php (z. B. processDatamapClass / processCmdmapClass) das etablierte Muster. Unter TYPO3\CMS\Core\DataHandling\Event dokumentiert Core derzeit v. a. Reference-Index- und Link-Parsing-Events — z. B. IsTableExcludedFromReferenceIndexEvent, AppendLinkHandlerElementsEvent — siehe DataHandling-Events in der Core-Doku und \TYPO3\CMS\Core\DataHandling\Event.

Verfügbare Hooks  

HookZeitpunktMethode
processDatamapClassVor/Nach DatenoperationenprocessDatamap_preProcessFieldArray, processDatamap_postProcessFieldArray, processDatamap_afterDatabaseOperations, processDatamap_afterAllOperations
processCmdmapClassVor/Nach BefehlenprocessCmdmap_preProcess, processCmdmap_postProcess, processCmdmap_deleteAction
clearCachePostProcNach Cache-ClearingBenutzerdefinierte Methode

Hook registrieren  

Praxisbeispiel: Auf neue Records reagieren  

Parameter des afterDatabaseOperations-Hooks
  • $status: 'new' oder 'update'
  • $table: Name der betroffenen Tabelle
  • $id: UID des Records (bei 'new': der NEW-Platzhalter)
  • $fieldArray: Array der tatsächlich geschriebenen Felder
  • $dataHandler: Die DataHandler-Instanz (Zugriff auf substNEWwithIDs)

Reference Index und Cache  

Reference Index aktualisieren  

Der Reference Index (sys_refindex) bildet alle Beziehungen zwischen Records ab. Der DataHandler aktualisiert ihn automatisch – nach Bulk-Operationen oder Migrationen sollten Sie ihn zusätzlich über die CLI prüfen:

v14: Reference Index unter Wartung

In TYPO3 v14 steht Referenzindex prüfen und aktualisieren unter Verwaltungswerkzeuge → System → Wartung (EXT:install), nicht mehr am früheren Low-Level-Einstieg. Auf der CLI bleibt vendor/bin/typo3 referenceindex:update sinnvoll für große Instanzen.

Cache-Invalidierung  

Der DataHandler invalidiert nach jeder Operation automatisch die relevanten Caches über Cache-Tags. Für jedes betroffene Record werden folgende Tags geflusht:

  • Tabellenname: z.B. pages, tt_content
  • Tabelle + UID: z.B. tt_content_123
  • Seiten-UID: z.B. pageId_10

Für manuelles Cache-Clearing verwenden Sie clear_cacheCmd:


Workspace-kompatibel entwickeln  

Wenn Ihr Code in einer Workspace-Umgebung läuft, erstellt der DataHandler automatisch versionierte Records. Das erfordert kein spezielles Handling – solange Sie den DataHandler nutzen.

Neu in v14: Der discard-Befehl  

TYPO3 v14 führt einen neuen DataHandler-Befehl ein, der Workspace-Änderungen verwirft – sauberer und expliziter als das bisherige version/clearWSID-Konstrukt:

Welche UID für `discard`?

Der Core akzeptiert in DataHandler::discard() die UID eines Live- oder Workspace-Datensatzes; bei Live-UID wird die Workspace-Overlay-Zeile aufgelöst. Siehe DataHandler::discard().


Häufige Fallstricke  


v14 Breaking Changes  

TYPO3 v14 entfernt mehrere öffentliche Properties des DataHandler und ändert das Verhalten bei Datumswerten. Hier die vollständige Übersicht:

ÄnderungForge IssueMigration
userid und admin Properties entfernt#107848Backend-User wird direkt aus $GLOBALS['BE_USER'] gelesen
storeLogMessages entfernt#106118log() schreibt jetzt immer in sys_log – keine Konfiguration nötig
copyWhichTables, neverHideAtCopy, copyTree entfernt#107856Werte werden aus BE_USER->uc gelesen (neverHideAtCopy, copyLevels)
Neuer discard-Befehl#107519Ersetzt version/clearWSID und version/flush für Workspace-Operationen
ISO8601-Datumswerte verbessert#105549Workarounds mit manuellen Timezone-Offsets entfernen
List- und Seitenmodul: Record API#107356 / #92434Vorschau/Transformationen auf `Record`-Objekte umstellen statt roher Arrays

ISO8601-Migration im Detail  

Bisher behandelte TYPO3 qualifizierte ISO8601-Datumswerte mit Z fälschlicherweise als Lokalzeit. v14 korrigiert das:

Property-Migration für v14  

Extension Scanner nutzen

Der TYPO3 Extension Scanner erkennt Zugriffe auf die entfernten Properties als Weak Match. Prüfen Sie Ihre Extensions vor dem v14-Upgrade.


Fazit  

DataHandler ist Pflicht

Für jede TCA-Tabelle. Rohes SQL umgeht Cache, Reference Index und Workspace-Integrität.

Zwei Arrays, volle Kontrolle

DataMap ($data) für Create/Update. CmdMap ($cmd) für Copy/Move/Delete. Immer als neue Instanz.

v14-Migration planen

Entfernte Properties prüfen, ISO8601-Workarounds entfernen, discard statt clearWSID verwenden.

Der DataHandler ist kein optionales Komfort-Feature – er ist die Voraussetzung für konsistente, workspace-fähige und wartbare TYPO3-Extensions. Investieren Sie die Zeit, ihn zu verstehen, und Ihre Extensions werden es Ihnen mit Stabilität und Zukunftssicherheit danken.

Für technisch Interessierte

TYPO3 DataHandler Skill

Agent-optimierte Referenz (Skill v2.0.0, Kompatibilität TYPO3 v13–v14): DataMap/CmdMap, Backend-Kontext, Reference Index, SC_OPTIONS-Hooks vs. dokumentierte PSR-14-Events. Im selben Ordner: SKILL.md, SKILL-PHP84.md, SKILL-CONTENT-BLOCKS.md.

Auf GitHub öffnen

Lassen Sie uns ueber Ihr Projekt sprechen

Standorte

  • Mattersburg
    Johann Nepomuk Bergerstraße 7/2/14
    7210 Mattersburg, Austria
  • Wien
    Ungargasse 64-66/3/404
    1030 Wien, Austria

Dieser Inhalt wurde teilweise mithilfe von KI erstellt.