Eine PHP-Anwendung zu internationalisieren bedeutet nicht nur, Schaltflächen und Meldungen zu übersetzen. Eine für mehrere Sprachen oder Märkte vorbereitete Anwendung muss Sprache, regionale Formate, Zeitzone, Währung, Inhalte und Geschäftsrichtlinien trennen. Werden diese Schichten vermischt, kann jede Erweiterung zu einer funktionalen Abspaltung werden, die schwer zu testen und zu warten ist.
Was sich beim Betrieb in mehreren Sprachen und Märkten ändert

Die Sprache bestimmt, wie ein Text ausgedrückt wird. Die regionale Einstellung oder Locale definiert Darstellungskonventionen wie das Dezimaltrennzeichen, die Reihenfolge von Datumsangaben oder die Tausendergruppierung. Eine Locale kann eine Region enthalten, etwa es-ES oder fr-CA, aber diese Region darf nicht Markt, Rechtsträger, Ansässigkeit, Geschäftspolitik oder Betriebsland ersetzen.
Auch Kontexte, die häufig gemeinsam auftreten, aber nicht dasselbe bedeuten, sollten unterschieden werden:
- Zeitzone: interpretiert Zeiten, Fristen, Kalender und operative Abschlüsse.
- Währung: identifiziert den Betrag einer Transaktion oder Preisliste; sie wird nicht aus der Sprache abgeleitet.
- Organisation oder Rechtsträger: kann Steuern, Berechtigungen, Rechnungsstellung oder Datenaufbewahrung bestimmen.
- Markt: kann Katalog, Logistik, Zahlungsmethoden oder verfügbare Kanäle beeinflussen.
- Nutzereinstellungen: gewählte Sprache, Locale und Zeitzone, die von der Unternehmenseinstellung abweichen können.
Eine Person kann die Benutzeroberfläche auf Englisch verwenden, in einer europäischen Zeitzone arbeiten und eine Organisation verwalten, die in einer anderen Währung abrechnet. Diese Realität auf eine einzige Variable locale zu reduzieren, erzeugt implizite Entscheidungen.
Der kostspielige Fehler: Sprache zur Geschäftsregel machen
Ein schlechtes Zeichen liegt vor, wenn der Code Domänenentscheidungen anhand der Sprache der Benutzeroberfläche trifft: if ($locale === 'es'). Diese Bedingung kann damit beginnen, ein anderes Label anzuzeigen, und damit enden, Steuern anzuwenden, eine Zahlungsmethode auszublenden oder eine Genehmigung zu ändern.
Die richtige Frage lautet: „Welche Daten oder Richtlinie erklären diese Abweichung?“ Wenn sie von einem Rechtsträger abhängt, muss dieser Rechtsträger abgefragt werden. Wenn sie auf eine Geschäftspolitik zurückgeht, muss eine identifizierbare und versionierbare Richtlinie existieren. Wenn sie nur die Darstellung betrifft, gehört sie an die Ein- oder Ausgabeschnittstelle.
Die Sprache lokalisiert das Nutzungserlebnis; sie autorisiert, berechnet oder definiert das Verhalten der Domäne nicht selbst.
Was in der Domäne verbleiben muss
Die Domäne muss mit stabilen Konzepten und kanonischen Werten arbeiten. Eine Bestellung benötigt Mengen, Beträge, Positionen, Zustände und Berechnungsregeln; sie muss nicht wissen, ob ein Betrag als 1,234.50 oder 1.234,50 angezeigt wird. Eine Berechtigungsrichtlinie muss explizite Attribute erhalten und darf nicht die Darstellung des Nutzers auslesen.
- Domäne: Invarianten, Zustände, Berechnungen, geschäftliche Autorisierungen, Richtlinien und Ereignisse.
- Anwendung: Anwendungsfälle, Laden des Kontexts, Koordination und Auswahl von Richtlinien.
- Eingabeadapter: Formulare, Header, APIs oder Dateien; Validierung und Normalisierung.
- Ausgabeadapter: Übersetzung, Serialisierung und Formatierung von Datumsangaben, Beträgen und Einheiten.
Vermeiden Sie in PHP, dass Entitäten und zentrale Services direkt Session, HTTP-Header, Umgebungsvariablen oder die globale Locale des Prozesses abfragen. Diese Abhängigkeiten führen dazu, dass sich derselbe Anwendungsfall je nach Kanal oder Ausführungszeitpunkt unterschiedlich verhält.
Einen expliziten und begrenzten Kontext entwerfen
Ein ExecutionContext kann die Kennung der Organisation, den Akteur, die Darstellungs-Locale und die bevorzugte Zeitzone enthalten. Jedes Feld muss eine klare Semantik haben. Die Währung einer Operation muss jedoch Teil des Betrags oder der angewendeten Preisrichtlinie sein, nicht einer veränderlichen globalen Präferenz.
Lösen Sie den Kontext am Rand jedes Kanals auf. Eine Webanfrage kann eine gespeicherte Präferenz oder kontrollierte Aushandlung verwenden; eine API muss explizite und dokumentierte Felder erhalten; ein Warteschlangenprozess muss die erforderlichen Kennungen bei seiner Erstellung persistieren. Ein asynchroner Job darf nicht annehmen, dass er Session, Nutzer oder Zeitzone erbt.
Übersetzbare Inhalte und operative Daten
Texte der Benutzeroberfläche, Kommunikationsvorlagen und redaktionelle Inhalte haben einen anderen Lebenszyklus als operative Daten. Verwenden Sie stabile und semantische Schlüssel, beispielsweise billing.invoice.overdue, statt des Originaltexts. Dadurch kann die Formulierung geändert werden, ohne Code, Tests oder Integrationen zu beschädigen.
Verwaltbare Inhalte erfordern eine Veröffentlichung: Eine Übersetzung kann als Entwurf vorliegen, genehmigt oder veröffentlicht sein. Definieren Sie den Fallback: angeforderte Sprache, Basissprache der Organisation und, falls zutreffend, ein sichtbares und kontrolliertes Fehlen. Eine alternative Übersetzung kann für eine interne Notiz akzeptabel sein, aber nicht unbedingt für eine vertragliche Kommunikation.
Duplizieren Sie keinen vollständigen operativen Datensatz je Sprache, außer wenn die Daten lokalisiert sind. Ein Produkt kann übersetzbare Namen und Beschreibungen haben, während Kennung, Gewicht, Status und Verfügbarkeitsregeln gemeinsam bleiben. Wenn ein tatsächlicher geschäftlicher Unterschied besteht, modellieren Sie ihn als Variante oder Richtlinie, nicht als Übersetzung.
Datumsangaben, Beträge, Einheiten und Rundungen
Speichern Sie Zeitpunkte eindeutig und bewahren Sie die Zeitzone, wenn die Bedeutung lokal ist. „Das Meeting beginnt um 09:00 Uhr“ erfordert die Kenntnis der Zone, in der es festgelegt wurde; „das Ereignis trat zu diesem Zeitpunkt ein“ erfordert einen absoluten Zeitpunkt. Saisonale Zeitumstellungen erzeugen nicht existierende oder doppelte Stunden; daher muss die Eingabe validiert und die getroffene Auflösung, wenn zutreffend, dokumentiert werden.
Speichern Sie für Geld einen ganzzahligen Betrag in Untereinheiten zusammen mit dem Währungscode, gehen Sie jedoch nicht von zwei Dezimalstellen aus. Die Skalierung oder der Exponent stammt aus den für die Operation geltenden Währungsmetadaten. Einige Währungen verwenden eine andere Skalierung als zwei, und historische Anforderungen oder die eines Zahlungsnetzwerks können erfordern, die effektive Skalierung oder eine Version der verwendeten Regel zu speichern.
final class Money {
public function __construct(
public readonly int $minorUnits,
public readonly string $currency,
public readonly int $scale
) {}
}
Die Skalierung ermöglicht die korrekte Interpretation der Untereinheiten, ersetzt jedoch keine Rundungsrichtlinie. Definieren Sie den Rundungszeitpunkt, den angewendeten Modus und gegebenenfalls die Bargeldregel, da sich die Kassenrundung von der buchhalterischen Rundung unterscheiden kann. Vermeiden Sie float, lokalisierte Formate während der Berechnung und implizite Konvertierungen.
Dasselbe Muster gilt für Maße: Bewahren Sie die ursprüngliche Einheit, wenn sie operative Bedeutung hat, normalisieren Sie sie, wenn die Berechnung dies erfordert, und konvertieren Sie nur bei der Erfassung oder Darstellung. Ein Formular muss die Einheit und das zulässige Format angeben; es darf nicht raten, ob 1,500 eins Komma fünf oder eintausendfünfhundert bedeutet.
Architektur von Ein- und Ausgabeflüssen
Die Trennung der Schichten muss in einem vollständigen und wiederholbaren Ablauf sichtbar sein:
- Kontext und Eingabedaten erfassen: Organisation, Akteur, Kanal, Locale, Zeitzone und den empfangenen Wert ermitteln.
- Das zulässige Format validieren: Pflichtfelder, Syntax, Einheit, Währung, Zeitzone und Kanalbeschränkungen prüfen.
- Auf kanonische Werte normalisieren: lokalisierten Text in eindeutige Beträge, Datumsangaben, Einheiten und Kennungen umwandeln.
- Den Domänenanwendungsfall ausführen: explizite Regeln und Richtlinien auf kanonische Werte anwenden.
- Die Ausgabe übersetzen und formatieren: veröffentlichte Meldungen auswählen und Werte für Empfänger oder API-Vertrag darstellen.
Eine API kann festlegen, nur kanonische Formate zu akzeptieren, etwa Datumsangaben mit expliziter Zone und strukturierte Beträge. Ein für Menschen bestimmtes Formular kann lokalisierte Formate akzeptieren, sofern sein Parser explizit ist. In beiden Fällen erhält die Domäne dieselbe stabile Repräsentation.
Konfigurierbare Richtlinie oder andere Geschäftsregel
Eine Variation ist häufig konfigurierbar, wenn sie denselben Prozess teilt und deklarierbare Parameter ändert, etwa ein Limit, eine Feiertagsliste oder eine durch Konfiguration definierte Berechnungsmethode. Diese Konfiguration benötigt ein Schema, eine Version, eine verantwortliche Person und Tests.
Der Unterschied offenbart eine andere Regel, wenn er Invarianten, Zustände, Verantwortlichkeiten, Datenquellen oder rechtliche Folgen verändert. Ihn in Optionen zu verstecken, erzeugt in diesem Fall eine undurchsichtige Konfiguration. Modellieren Sie eine Richtlinie über eine explizite Schnittstelle oder einen separaten Ablauf, wenn der Prozess tatsächlich anders ist. Das Ziel ist nicht, eine einzige Abstraktion zu erzwingen, sondern zu vermeiden, die gesamte Anwendung wegen eines lokal begrenzten Unterschieds zu duplizieren.
Tests und Checkliste

Tests müssen Berechnung und Darstellung verifizieren. Das Ändern von Sprache oder Locale darf einen Gesamtbetrag, eine Autorisierung oder eine Geschäftspolitik nicht verändern, sofern dies nicht durch eine explizite Anforderung festgelegt ist.
- Testen Sie Datumsangaben bei Zeitumstellungen sowie mit mehrdeutigen und nicht existierenden Stunden.
- Decken Sie Null- und Negativbeträge, unterschiedliche Skalierungen sowie buchhalterische Rundung und Kassenrundung ab.
- Prüfen Sie zulässige lokalisierte Eingaben und die Ablehnung mehrdeutiger Formate.
- Verifizieren Sie Fallback, fehlende veröffentlichte Inhalte und interpolierte Variablen.
- Führen Sie asynchrone Jobs ohne Session aus und verwenden Sie nur persistierten Kontext.
- Testen Sie API-Verträge mit kanonischen Werten und Formatmetadaten, wenn diese erforderlich sind.
Bevor Sie eine Sprache oder einen Markt aktivieren, identifizieren Sie, was sich tatsächlich ändert, trennen Sie die jeweiligen maßgeblichen Datenquellen, überprüfen Sie Währungs- und Zeitregeln und aktivieren Sie die Verfügbarkeit schrittweise, wenn der Betrieb eine kontrollierte Validierung erfordert. Diese Disziplin ermöglicht es, die Anwendung zu erweitern, ohne jeden Markt in eine parallele Produktversion zu verwandeln.



