Sin impuesto Con impuesto

Aufbau eines modernen Moduls für PrestaShop 8 und 9

Ein Modul von 2026 ist keine riesige PHP-Datei. Wir zeigen Ihnen die Struktur, die wir verwenden, damit es wartbar bleibt, den Addons-Validator besteht und Updates übersteht.

Jesús Meilán
Updated: 26/09/2026 103
Aufbau eines modernen Moduls für PrestaShop 8 und 9
Share:

Viele Module sind noch so geschrieben wie zu PrestaShop 1.6: eine Hauptdatei mit Tausenden Zeilen, handgeschriebenes SQL und Formulare mit HelperForm. Sie funktionieren, sind aber sehr aufwendig zu pflegen. Das ist die Struktur, der wir in unseren Modulen für PrestaShop 8 und 9 folgen.

Der Ordnerbaum

mimodulo/
├── mimodulo.php          # Hauptklasse: Installation, Hooks, wenig mehr
├── composer.json         # PSR-4-Autoload des Namespace
├── config/
│   ├── services.yml      # Symfony-Services
│   └── routes.yml        # Back-Office-Routen
├── src/
│   ├── Controller/Admin/ # Symfony-Controller
│   ├── Entity/ oder Repository/
│   └── Service/          # Geschäftslogik, testbar
├── views/
│   ├── templates/hook/   # Smarty-Templates des Frontends
│   ├── templates/admin/  # Twig-Templates des Back-Office
│   ├── css/ js/ img/
├── upgrade/              # upgrade-1.1.0.php, upgrade-1.2.0.php…
├── translations/
└── logo.png

Die Hauptklasse, schlank

Die Datei mimodulo.php sollte sich darauf beschränken, das Modul zu deklarieren, zu installieren und zu delegieren. Die eigentliche Logik gehört in Klassen unter src/, die sich separat testen lassen:

public function hookActionValidateOrder(array $params)
{
    $this->get('mimodulo.order_notifier')->notify($params['order']);
}

Composer und Namespace

{
  "name": "rekire/mimodulo",
  "autoload": { "psr-4": { "Rekire\\MiModulo\\": "src/" } },
  "config": { "prepend-autoloader": false },
  "type": "prestashop-module"
}

Die Option prepend-autoloader: false verhindert, dass sich Ihr Autoloader vor den von PrestaShop setzt, was zu Versionskonflikten mit Bibliotheken führen kann, die der Core bereits mitbringt.

Vorsicht bei gemeinsam genutzten Bibliotheken: Wenn zwei Module jeweils ihre eigene Kopie eines SDK mitbringen (das von Stripe ist der klassische Fall) und beide in derselben Anfrage geladen werden, scheitert PHP mit „Cannot declare class“. Laden Sie Abhängigkeiten nur, wenn die Klasse noch nicht existiert, oder isolieren Sie sie mit einem Namespace-Präfix.

Backoffice mit Symfony

In PrestaShop 8 und 9 können Konfigurationsseiten Symfony-Controller mit Symfony-Formularen und Twig-Templates sein, deklariert in config/routes.yml. So fügen sie sich in Menü, Berechtigungen und CSRF-Tokens des Backoffice ein, ohne dass man diese neu erfinden muss.

Upgrades vom ersten Tag an

Jede Version, die die Datenbank ändert, neue Hooks registriert oder Tabs anlegt, bringt ihr upgrade/upgrade-X.Y.Z.php mit. Und dieses Skript muss idempotent sein: Wird es zweimal ausgeführt, verdoppelt es nichts. Das verhindert doppelte Tabs im Menü oder Spalten, deren Anlage fehlschlägt.

Validierung vor der Veröffentlichung

  • Lizenzkopf in allen Dateien.
  • Escaping von Variablen in Smarty (|escape:'html':'UTF-8').
  • Keine Funktionen, die der Addons-Validator verbietet.
  • index.php in jedem Ordner.
  • Tests auf mindestens zwei PrestaShop-Versionen und mit aktivem Debug-Modus: Warnungen, die man im Live-Betrieb nicht sieht, zählen im Kompatibilitätsbericht sehr wohl.

Mit dieser Struktur kann ein Modul über Jahre wachsen, ohne zu einer Datei zu werden, die sich niemand mehr anzufassen traut.

Laden...
Cookie-Zustimmung
Zum Seitenanfang