dbxDB, DD und FD bilden die Datenbasis von dbxapp. Fachcode arbeitet nicht direkt mit PDO und kennt im Normalfall auch keinen physischen Tabellennamen. Er verwendet eine DD-Referenz wie dbxWorkflow|workflowDefinition.
Einordnung im Golden Path
Verbindliches Modulhandbuch zeigt dieselbe Datenpipeline in einem vollständigen Modul. Dieses Kapitel ist die vertiefende Referenz für Abfragen, Schreiben, DD/FD und Schemaabgleich.
Zusammenspiel
| Baustein | Verantwortung | Typischer Ort |
|---|---|---|
| dbxDB | Lesen, Schreiben, Rechte, Owner-Filter, Trace und DB-Abstraktion | dbx/include/dbxDB.class.php |
| dbxDD | DD-Modell lesen sowie DD und physische DB synchronisieren | dbx/include/dbxDD.class.php |
| DD | Tabelle, Felder, Indizes, Rechte, Defaults, Validierung | dbx/modules/{modul}/dd/*.dd.php |
| FD | Formularsicht auf DD-Felder: Reihenfolge, Template, Label, Optionen | dbx/modules/{modul}/fd/*.fd.php |
Eine explizite Referenz besteht aus Modul und DD-Name:
Ohne Modulpräfix sucht dbxapp zuerst im aktiven Modul und anschließend im Kernmodul dbx. In wiederverwendbarem Fachcode ist die explizite Referenz meist verständlicher und verhindert Namenskollisionen.
dbxDB und dbxDD als stabile Fassaden
dbxDB ist groß, weil Verbindung, DD-Auflösung, Rechte, Owner-Filter, Transaktionen, Trace, Fehler und DB-Abstraktion in jedem Modul gleich funktionieren müssen. dbxDD erweitert diese Fassade um Schema-, Backup-, Restore- und Transferprozesse.
Die Klassen werden nicht nach Zeilenzahl geteilt. Eine interne Extraktion ist nur sinnvoll, wenn eine eigenständige Verantwortung mit Tests und kompatibler öffentlicher API nachgewiesen ist. Fachmodule verwenden weiterhin dbxDB/dbxDD als einzigen Einstieg und kennen keine internen Helfer.
Eine vollständige DD
Das folgende Muster entspricht dem von dbxapp exportierten DD-Format. Tabelle, Felder und Indexe stehen direkt in den Abschnitten TABLE, FIELDS und INDEXES. Jedes Feld ist vollständig sichtbar und wird anschließend mit $fields[]=$field angehängt. Lokale $addField-Closures oder andere Hilfsabstraktionen gehören nicht in eine DD.
Verbindliche reale Beispiele sind dbx/modules/dbx/dd/dbxMissing.dd.php und die beiden DDs des myInvoices-Referenzmoduls.
Wichtige Tabellenattribute
| Attribut | Bedeutung |
|---|---|
| server | Konfigurierter DB-Server oder modulbezogene SQLite-Datei |
| table | Physischer Tabellenname |
| primary | Primärschlüssel; Standard ist id |
| language | 0 neutral, Sprachcode fest oder * dynamisch |
| autosync | Tabelle darf aus der DD synchronisiert werden |
| trash | Papierkorb-/Trace-Verhalten der Tabelle |
| trace | Änderungen werden über die DB-Pipeline nachvollziehbar protokolliert |
| read/create/update/delete | Gruppenrechte für die jeweilige Operation |
| read_owner/update_owner | Owner-basierte Rechte; dbxDB ergänzt den Owner-Filter |
owner, Zeitstempel und trash sind keine Pflicht für jede Tabelle. Sie sollten aber gemeinsam und bewusst eingesetzt werden, wenn Eigentum, Nachvollziehbarkeit oder Soft-Delete fachlich benötigt werden.
Sind create_date, create_uid, owner, update_date und update_uid in der DD vorhanden, setzt dbxDB sie automatisch. Ein Fachmodul soll diese Infrastrukturwerte weder im Formular noch vor insert(), update() oder save() nachbauen.
Lokale Serverbindung pro DD
$table['server'] ist der ausgelieferte Standard, nicht eine globale Festlegung für das ganze System. Eine Installation kann jede DD in config.local.php einzeln auf eine DB3-Datei oder einen aktiven SQL-Server binden. dbxDB löst diese Bindung zentral auf; Fachmodule bleiben unverändert.
Ungültige explizite Bindungen werden abgelehnt und fallen nicht unbemerkt auf den DD-Standard zurück. Installation, Migration, Sicherung und Rollback sind unter Installation, Updates und DD-Serverbindungen verbindlich beschrieben.
Feldattribute
| Attribut | Bedeutung |
|---|---|
| name, type, length | Datenbankfeld und Datentyp |
| index | z. B. PRI, UNI oder MUL |
| default | Default für neue bzw. leere Datensätze |
| rules | Validator-Regeln, z. B. int, parameter, email, min, max |
| tpl | Standard-Feldtemplate für dbxForm |
| options | Auswahlwerte, gewöhnlich wert=Label&wert2=Label2 |
| data | Template-Daten, z. B. rows=6 |
| convert | Ausgabe-/Eingabekonvertierung |
FD: eine Formularsicht auf die DD
Die DD beschreibt die fachliche Datenstruktur. Eine FD wählt daraus die Formularfelder aus, ordnet sie und kann Darstellungseigenschaften überschreiben. So können Bearbeiten-, Such- und Schnellformular dieselbe DD unterschiedlich darstellen.
Sprachversionen und Meldungen
Eine FD enthält sichtbare Labels, Optionen, Platzhalter und Meldungen. Deshalb gibt es für jede FD eine deutsche, englische und spanische Fassung:
| Sprache | Datei | save_success | save_error |
|---|---|---|---|
| Deutsch | task-form.fd.php oder task-form_de.fd.php | Daten wurden gespeichert | Daten konnten nicht gespeichert werden |
| Englisch | task-form_en.fd.php | Data was saved | Data could not be saved |
| Spanisch | task-form_es.fd.php | Los datos se guardaron | Los datos no se pudieron guardar |
dbxForm löst die Datei über die aktive Sprache auf, lädt $fields und $messages gemeinsam und hält beides im zentralen FD-Cache. dbxReport erbt genau denselben Ablauf. Der verbindliche Schlüssel heißt save_success; save_succeass wird nur als kompatibler Alias mitgeführt.
Eine DD erhält dagegen nur dann Sprachdateien, wenn tatsächlich getrennte Sprachtabellen existieren. Sichtbare Übersetzungen allein sind kein Grund, eine DD zu duplizieren.
Möglichkeiten:
- Nur _dd setzen: dbxForm verwendet Feldangaben der DD.
- _dd und _fd setzen: Die FD bestimmt die konkrete Formularsicht.
- Einzelne Felder manuell ergänzen oder gezielt DD-Werte mit dd:: verwenden.
- Für einen Report eine eigene Selection-FD mit dbx_rwhere, dbx_rsort, dbx_rdesc, dbx_rrows und optional dbx_rselect verwenden.
dbxDB lesen
Einen Datensatz lesen
Eine Integer-WHERE wird gegen den in der DD definierten Primärschlüssel aufgelöst. Spalten können begrenzt werden:
select1() liefert bei keinem Treffer die leere Standardstruktur der DD. Deshalb sollte Fachcode nicht nur is_array() prüfen, sondern auch die ID:
Listen, Sortierung und Pagination
Die Parameter nach $columns sind orderby, ASC|DESC, groupby, max, offset und verify_access. Stammt Sortierung aus einem Request, müssen Spaltenname und Richtung vorher gegen feste Allowlists geprüft werden; sie sind keine freien Suchwerte.
Sichere Suche
Array-WHEREs validieren Felder gegen die DD und escapen Werte zentral:
Für ein einzelnes LIKE-Feld ist ebenfalls eine strukturierte Form möglich:
Neue Request-Suchen sollten diese Formen verwenden. Ein String-WHERE bleibt für bestehenden und intern aufgebauten Code möglich, darf aber nicht durch unkontrolliertes Konkatenieren von Benutzereingaben entstehen.
Zählen
dbxDB schreiben
Automatische Systemfelder
Bei insert() setzt dbxDB automatisch:
- create_date
- create_uid
- owner
- update_date
- update_uid
Bei update() setzt dbxDB automatisch update_date und update_uid. dbxForm::save_post() verwendet dieselbe dbxDB-Pipeline. Die Automatik ist ein wesentlicher Vorteil der DD-Nutzung: alle Module erhalten identische Audit- und Owner-Werte, ohne sie selbst zu verwalten.
Insert
insert() liefert 1 bei Erfolg. Die neue ID wird anschließend gelesen:
Update
Insert oder Update mit save()
save() aktualisiert bei vorhandener WHERE/RID und fügt sonst ein. Für fachlich komplexe Speicherungen sind getrennte Insert-/Update-Zweige oft lesbarer; für Standardformulare verwendet dbxForm::save_post() intern diesen Weg.
Delete
Ein Delete ohne WHERE wird von dbxDB blockiert. Ob eine Tabelle wirklich gelöscht, getraced oder über einen fachlichen Papierkorb behandelt werden soll, entscheidet das Modul zusammen mit der DD. Nicht eigenmächtig Rechte- oder Trace-Prüfungen deaktivieren.
Parameter für Rechte, Felder, Werte und Trace
Die Schreibmethoden besitzen am Ende Infrastruktur-Schalter:
Im Fachmodul bleiben alle Werte normalerweise 1. Aufrufe mit 0 sind nur für klar begrenzte Systempfade vorgesehen, etwa Installation, interne Synchronisation oder bereits separat geschützte Infrastruktur. Reale Beispiele dazu stehen in dbxWorkflowEngine, dbxContentLngSync und dbxShopRepository.
Baumdaten
Für Parent-/Child-Strukturen kann select_tree() Ordner und optionale Items gemeinsam normalisieren:
Die konkrete CMS-DD wird sprachabhängig über dbxContentLng ermittelt. Das Beispiel zeigt die API; CMS-Code sollte die vorhandenen Resolver verwenden.
DD-Modell lesen
Das ist für Generatoren, Admin-Werkzeuge und Workflow-Bindings sinnvoll. Fachcode sollte seine Geschäftslogik nicht bei jedem Request dynamisch aus Felddefinitionen erraten.
DD und Datenbank synchronisieren
DD-Sync ist ein schrittweiser Prozess. Das robuste Muster aus den aktuellen Modulen setzt den Prozess zurück und ruft apply auf, bis er fertig ist:
Verfügbare Einsatzarten:
- plan/check: Unterschiede anzeigen, ohne das Schema anzuwenden.
- reset: gespeicherten Prozesszustand zurücksetzen.
- apply: geplante Schritte kontrolliert anwenden.
- force: nur in dafür vorgesehenen Admin-/Installationspfaden erzwingen.
- sync_db_to_dd(...): eine bestehende DB-Struktur in eine DD übernehmen oder mit ihr zusammenführen.
DB nach DD ist keine normale Fachaktion. Sie gehört in Schema-/Wizard-Werkzeuge und muss anschließend als vollständige, lesbare DD geprüft werden.
Datenbanksysteme
dbxDB kapselt den Zugriff über PDO. Unterstützt werden – abhängig von Konfiguration und PHP-Treibern – unter anderem SQLite, MySQL/MariaDB, PostgreSQL, SQL Server, Oracle, Firebird sowie weitere PDO-Treiber. Eine DD darf daher keine SQLite-spezifische Fachlogik erzwingen. Unterschiede bei Schema und Limits werden in dbxDB/dbxDD behandelt.
Verbindliche Regeln
- Fachmodule verwenden dbxDB, nicht direkt PDO.
- DD ist die versionierbare Wahrheit der Tabellenstruktur.
- FD beschreibt eine Formularsicht und dupliziert nicht unnötig das Datenmodell.
- Request-Werte werden validiert; Suchbedingungen bevorzugen Array-WHEREs.
- HTML gehört nicht in Datenbankmethoden und SQL nicht in Templates.
- verify_access=0 und trace=0 sind begründete Infrastruktur-Ausnahmen.
- DD-Sync wird vollständig bis finished ausgeführt und auf Fehler geprüft.
- Jede neue Tabelle erhält eine eigene DD und einen eindeutigen DD-Namen.
- Automatische Owner-, Benutzer- und Zeitfelder werden nicht im Modul dupliziert.
Reale Referenzen
- dbx/modules/dbxWorkflow/dd/workflowDefinition.dd.php: vollständige DD.
- dbx/modules/dbxWorkflow/fd/workflow-definition.fd.php: Formularsicht.
- dbx/modules/dbxWorkflow/include/dbxWorkflowEngine.class.php: CRUD mit Array-WHEREs und fachlicher Persistenz.
- dbx/modules/dbxShop/include/dbxShopRepository.class.php: DD-Sync und umfangreicher Repository-Zugriff.
- dbx/modules/dbxContent/include/dbxContentLngSync.class.php: sprachabhängige DDs und kontrollierte Systemschreibvorgänge.
- Verbindliches Modulhandbuch — vollständiger, verbindlicher Modulablauf.
- DB3-MySQL-DB3-Roundtrip — getesteter DB3-MySQL-DB3-Transfer.