Files
4plants/Doku/php.md
T
2026-06-17 17:09:06 +00:00

4.6 KiB

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<T>).
    • 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.