# PHP & Symfony Engineering Guidelines ## 1. Core PHP Standard Wir schreiben modernen, typensicheren und expliziten Code. Ziel ist es, Fehler zur Compile-Zeit bzw. via statischer Analyse zu finden. * **Strict Typing:** Jede Datei beginnt zwingend mit `declare(strict_types=1);`. * **Typisierung:** * Konsequentes Type Hinting für alle Parameter und Rückgabewerte (inkl. `void`). * Nutzung von Union- und Intersection Types. * `mixed` ist verboten, außer in absolut unvermeidbaren Generics. * **Modern Features (PHP 8.2+):** * **Readonly:** Standard für DTOs, Value Objects und Services (`readonly class`). * **Constructor Promotion:** Nutzung zur Reduktion von Boilerplate. * **Enums:** Einsatz anstelle von Konstanten oder Strings für feste Zustände. * **Match Expression:** Bevorzugt gegenüber `switch`. * **Anti-Magic:** Magic Methods (`__call`, `__get` etc.) und dynamische Properties sind **strikt verboten**. ## 2. Control Flow & Readability Lesbarkeit schlägt akademische Perfektion. Code muss für andere Senioren ohne "Rätselraten" sofort verstehbar sein. * **Control Flow:** Nutzung von **Early Returns** und **Guard Clauses**. Verschachtelte `if-else`-Strukturen sind zu vermeiden, um die kognitive Last gering zu halten. * **Self-Explaining Code:** Namen müssen den Intent beschreiben (`calculateTotalTax()` statt `calc()`). Booleans beginnen mit `is`, `has` oder `can`. * **Kommentare:** Kommentare werden nur eingesetzt, wenn: 1. Der Code aufgrund einer Sonderlösung **nicht selbsterklärend** ist (Dokumentation des "Warum"). 2. **Arrays/Collections typisiert** werden müssen (`/** @var UserDTO[] $users */`), sofern PHPStan dies nicht anders erfassen kann. ## 3. Data Structures & Collections Wir vermeiden "Mystery Meat"-Datenstrukturen zugunsten von Typsicherheit. * **No Associative Arrays:** Die Nutzung von assoziativen Arrays als Pseudo-Objekte/Datencontainer ist verboten. Es werden immer **dedizierte Objekte (DTOs)** verwendet. * **Collections:** * **Transport:** Für einfache Listen, die nur durchiteriert werden, reichen typisierte Arrays (`array`). * **Domain-Logik:** Sobald eine Liste fachliche Logik besitzt (z.B. Filterung, Aggregation), wird eine dedizierte **Collection-Klasse** erstellt (implementiert `IteratorAggregate` und `Countable`). ## 4. Infrastructure & Symfony Implementation Symfony ist der Adapter zur Außenwelt, nicht das Zentrum der Applikation. * **Dependency Injection:** Ausschließlich **Constructor Injection**. Kein Service-Locator (`$this->container->get()`). DI erfolgt primär gegen Interfaces (Ports). * **Controller:** "Thin Controller". Aufgaben sind: Request-Daten validieren/extrahieren $\rightarrow$ Application-Service aufrufen $\rightarrow$ Response transformieren. Keine Business-Logik im Controller. * **Third-Party SDKs:** Alle externen Services/SDKs werden konsequent hinter einem **eigenen Interface (Port)** in der Infrastructure-Schicht gekapselt. Vendor-Klassen dürfen niemals den Application- oder Domain-Layer erreichen. ## 5. Persistence & Entity Design Wir minimieren die Koppelung an das ORM, um Performance und Testbarkeit zu sichern. * **Simple Entities:** Entitäten werden flach gehalten. * **Avoid Joins:** Gejointe Entitäten (komplexe `@ManyToOne` / `@OneToMany`) sind grundsätzlich zu vermeiden. Referenzen erfolgen über **IDs**. Die Zusammenführung erfolgt explizit in den Repositories/Services. * **Mapping:** Transformationen zwischen Infrastructure-Entities und Domain-Modellen erfolgen ausschließlich über dedizierte **Mapper-Klassen in der Dataschicht**. ## 6. Validation Pipeline (Shift-Left) Fehler werden so früh wie möglich abgefangen: `Request` $\rightarrow$ `DTO Asserts/Validation` $\rightarrow$ `Application Logic` $\rightarrow$ `Domain Complex Tests`. ## 7. Quality Gates & Workflow (Definition of Done) Bevor Code in ein Review geht, müssen folgende lokale Checks erfolgreich durchlaufen sein: 1. **Syntax Check:** `php -l` 2. **Statische Analyse:** `phpstan analyse` (Ziel Level 8/9). *Pragmatismus-Regel:* Wenn Typisierung die Lesbarkeit massiv zerstört $\rightarrow$ Review-Dialog statt "Force-Typing". 3. **Automatisierte Tests:** `phpunit` (Unit, Integration, Functional). --- ### Die Golden Rules im Überblick: 1. **Kein Framework / Keine Vendor-Klassen im Domain.** 2. **Flache Entitäten / Referenzen über IDs.** 3. **Immutability by Default (`readonly`).** 4. **Keine assoziativen Arrays $\rightarrow$ Dedizierte Objekte.** 5. **Early Returns $\rightarrow$ Flacher Code.** 6. **Local Check: `php -l` $\rightarrow$ `phpstan` $\rightarrow$ `phpunit`.**