Magento 2 Experten — Hyvä Theme, Tailwind CSS & SEO aus einer Hand ›

Preference/Rewrite: wann eine Preference statt eines Plugins nötig ist

Preference/Rewrite: wann eine Preference statt eines Plugins nötig ist

~7 Min. Lesezeit Zuletzt aktualisiert am 9. August 2026

CLAUDE.md, die verbindlichen Coding-Regeln dieses Projekts, sagt es klar: "Plugins (Interceptors) statt Preferences verwenden." Das ist kein Stilmittel, sondern eine bewusste Voreinstellung mit gutem Grund - und Block 5 hat diese Regel bislang eingehalten: zwei Plugins (Kapitel 38/39), null Preferences. Dieses Kapitel erklärt ehrlich, wann diese Voreinstellung an ihre Grenze stößt, bevor Kapitel 41 den konkreten Ausnahmefall dieser Serie umsetzt.

Was ist eine Preference technisch?

Eine Preference ist ein einfacher Eintrag in di.xml: <preference for="Interface" type="Implementierung"/>. Anders als ein Plugin passiert hier keine Codegenerierung und kein Interceptor-Wrapping - der DI-Container merkt sich beim Aufbau des Objektgraphen schlicht: "wird Interface angefragt, liefere eine Instanz von Implementierung". Es handelt sich um einen vollständigen, einmaligen Austausch der Klasse selbst, nicht um eine punktuelle Methoden-Interzeption zur Laufzeit.

Warum Plugins der Standard sind

Der Grund für die CLAUDE.md-Regel ist rein praktisch: Plugins sind additiv und nicht-destruktiv. Beliebig viele Module können denselben Interceptor-Punkt gemeinsam nutzen (Kapitel 43 zeigt, wie sortOrder die Reihenfolge regelt), der PHP-Compiler prüft Methoden-Signaturen bei setup:di:compile und meldet Inkompatibilitäten sofort, und ein einzelnes Modul zu deaktivieren nimmt nie versehentlich die komplette Logik eines anderen Moduls mit. Eine Preference dagegen ist ein Alles-oder-nichts-Austausch: genau eine Implementierung gewinnt pro Interface (Kapitel 42 vertieft, was das im Konfliktfall bedeutet).

Die drei echten Ausnahmen

  1. Die Zielmethode ist final oder nicht öffentlich zugänglich - ein Interceptor müsste sie per Vererbung überschreiben, und genau das verbietet PHP bei final-Methoden mit einem Fatal Error, bei private/protected-Methoden ganz grundsätzlich (Kapitel 38). Kein Plugin kann hier ansetzen, egal wie der Anwendungsfall aussieht.
  2. Konstruktor-Verhalten muss verändert werden - andere Default-Werte, eine andere injizierte Abhängigkeit, ein komplett anderer Aufbau des Objekts. Plugins fangen grundsätzlich niemals __construct() ab, unabhängig von final/private.
  3. Die komplette Implementierung hinter einem Interface muss ausgetauscht werden, nicht nur eine einzelne Methode angepasst - etwa weil ein Drittanbieter-Modul ein Interface auf eine Art implementiert, die für den eigenen Prozess grundlegend nicht passt, nicht nur an einer Stelle abweicht.

Vorschau: das konkrete Beispiel aus Kapitel 41

Kapitel 41 nutzt den ersten Fall: eine bereits im Projekt lizenzierte Drittanbieter-Erweiterung zur ERP-Anbindung der B2B-Sonderkonditionen (Kapitel 22) liefert eine Berechnungsmethode, die der Hersteller bewusst als final deklariert hat - und die Anforderung besteht trotzdem darin, ihr Ergebnis mit projektspezifischer Logik zu kombinieren.

Tipp: Die Prüfreihenfolge dieser Serie in einem Satz: erst fragen, ob ein passendes Event existiert (Observer, Kapitel 29-37), dann prüfen, ob eine Methoden-Interzeption reicht (Plugin, Kapitel 38-39), und erst wenn beides technisch ausscheidet, zur Preference greifen. Diese Reihenfolge ist kein Zufall - sie steigt in genau der Reihenfolge an, wie stark der Eingriff mit künftigen Magento- und Drittanbieter-Updates kollidieren kann.

Achtung: Bevor eine Preference geschrieben wird: wirklich sicherstellen, dass kein Plugin-fähiger Ansatzpunkt existiert. In der Praxis greifen viele Entwicklerinnen und Entwickler zur Preference, weil sie das Muster aus älteren Magento-1-Projekten ("Rewrites") kennen - nicht, weil es technisch erforderlich wäre. Jede Preference, die sich im Nachhinein auch als Plugin hätte lösen lassen, ist unnötig übernommenes Kompatibilitätsrisiko (Kapitel 42).