PHP-Entwickler in Wuppertal

PHP-Entwicklung für Unternehmen in Wuppertal mit Schwerpunkt Composer: composer.lock im Repository, Versionsangaben, composer audit, aufgegebene Pakete und Updates in kleinen Schritten mit Tests. Ein Einzelentwickler, remote und schriftlich.

PHP-Entwickler

Mein Platz in der WordPress-Community

  • Mein wordpress.org-Konto besteht seit 2006.
  • Ich habe zum WordPress-Core in den Versionen 7.0 und 7.1 beigetragen.
  • Ich betreue 30 Plugins auf wordpress.org.
  • Ich organisiere WordCamps und trete dort als Speaker auf.
  • Ich war bei jedem WordCamp Europe von 2017 bis 2026 dabei.

Mein WordPress.org-Profil

#Composer-Abhängigkeiten: worum es auf dieser Seite geht

Ich bin Mariusz Szatkowski, schreibe PHP, seit 2006 auch für WordPress, und arbeite als einzelner Entwickler von Gdynia aus. Für Unternehmen in Wuppertal übernehme ich eigene PHP-Anwendungen, Kundenportale, Laravel- und Symfony-Backends sowie Schnittstellen. Diese Seite hat einen Schwerpunkt: die Pakete, die Ihre Anwendung über Composer einbindet.

In den meisten PHP-Anwendungen ist der größere Teil des Codes fremder Code. Er liegt im Ordner vendor, niemand liest ihn, und er altert. Ein Hinweis auf eine Sicherheitslücke betrifft dann nicht Ihren eigenen Code, sondern ein Paket, dessen Namen in Ihrem Haus niemand mehr kennt. Wie ich das in den Griff bekomme, beschreibe ich hier: mit Befehlen, die ich am 11. November 2026 selbst ausgeführt habe, und mit den Aussagen der Composer-Dokumentation.

Ich arbeite nur aus der Ferne und in Textform, Termine und Anrufe gibt es nicht. Reine WordPress-Projekte haben eine eigene Seite: WordPress-Entwickler Wuppertal.

#composer.lock gehört ins Repository

Die Composer-Dokumentation sagt es deutlich: Die Datei composer.lock wird in die Versionsverwaltung eingecheckt. Dann installieren CI-Server, Produktionsserver und alle Entwickler dieselben Versionen. Auch wer allein arbeitet, bekommt nach sechs Monaten bei einer Neuinstallation dieselben Pakete wie damals, obwohl es inzwischen neue Versionen gibt.

Der Unterschied der beiden Befehle ist der Kern:

  • composer install nutzt bei vorhandener Lock-Datei exakt die dort eingetragenen Versionen.
  • composer update löst die Angaben der composer.json neu auf, schreibt neue Versionen in die Lock-Datei und installiert sie.

Auf einem Produktionsserver läuft deshalb composer install, nie composer update. Der Ordner vendor gehört laut Dokumentation in die .gitignore. Wer ihn eincheckt oder ohne Lock-Datei deployt, hat bei jedem Deployment eine andere Paketlage.

Mit composer validate prüft Composer, ob die composer.json gültig und die Lock-Datei auf dem Stand ist. Die Dokumentation empfiehlt den Aufruf vor jedem Commit dieser Dateien.

#Versionsangaben in der composer.json

Wie weit ein Update gehen darf, steht in der composer.json. Die Dokumentation zu Versionen beschreibt die Schreibweisen. Die wichtigsten:

AngabeBedeutung laut DokumentationFolge für Updates
7.4.0genau diese Versionkein Update ohne Änderung der Datei, auch kein Sicherheits-Patch
~1.2.3>=1.2.3 <1.3.0nur Patch-Versionen
~1.2>=1.2 <2.0.0Minor- und Patch-Versionen
^1.2.3>=1.2.3 <2.0.0alle Versionen bis zur nächsten Major-Version
^0.3>=0.3.0 <0.4.0vor 1.0 ist der Rahmen enger
* oder >=1.0ohne Obergrenzejede künftige Major-Version, auch eine inkompatible

Die Dokumentation rät bei offenen Bereichen ausdrücklich zum Caret-Operator, weil sonst unerwartet Versionen installiert werden, die Abwärtskompatibilität brechen. composer validate warnt vor solchen Angaben: Bei einer Testdatei mit "guzzlehttp/guzzle": "*" meldete es unbound version constraints (*) should be avoided.

Der Fall am anderen Ende ist genauso häufig. Wer ein Paket auf eine einzelne Version festnagelt, weil ein Update einmal etwas zerbrochen hat, bekommt später auch keine Sicherheitskorrektur mehr. Das Beispiel unten zeigt, was das bedeutet.

#composer audit: was geprüft wird und woher die Daten kommen

Laut Dokumentation zum Befehl prüft composer audit die installierten Pakete gegen definierte Regeln, vor allem gegen Sicherheitshinweise. Standardquelle ist die API von Packagist.org. Der Befehl erkennt außerdem aufgegebene Pakete. Er endet mit Exit-Code 0 ohne Funde und mit 1, wenn Pakete betroffen sind. Das macht ihn für eine Pipeline brauchbar: Ein Fund lässt den Build rot werden.

Nützliche Optionen aus der Dokumentation:

  • --locked prüft die Lock-Datei, unabhängig davon, was gerade in vendor liegt.
  • --no-dev lässt die Pakete aus require-dev aus.
  • --direct prüft nur direkt angeforderte Pakete, ohne Abhängigkeiten von Abhängigkeiten.
  • --format kennt table, plain, json und summary.

Hinter den Hinweisen steht laut Packagist eine Sammlung aus den GitHub Security Advisories und der FriendsOfPHP-Datenbank. Jeder Hinweis bekommt eine PKSA-Kennung, dazu kommen gegebenenfalls CVE- und GHSA-Nummern. Die README der FriendsOfPHP-Datenbank schreibt, dass sie nicht die Hauptquelle für Sicherheitsfragen ist und für keine der erfassten Software maßgeblich: Sie bündelt Hinweise zur bequemen Auswertung. Für ein Paket, das Ihnen wichtig ist, lese ich deshalb auch die Mitteilungen des Herstellers.

#Ein Lauf vom 11. November 2026

Zur Probe habe ich in einem leeren Verzeichnis ein Projekt mit Composer 2.5.5 und PHP 8.4 angelegt und zwei Pakete eingebunden: Guzzle als exakte Version 7.4.0 und das Paket swiftmailer/swiftmailer.

composer require guzzlehttp/guzzle:7.4.0 swiftmailer/swiftmailer
# Package swiftmailer/swiftmailer is abandoned, you should avoid using it.
# Use symfony/mailer instead.
# Found 14 security vulnerability advisories affecting 1 package.

Ergebnis: 14 Hinweise für Guzzle 7.4.0, die ältesten von 2022, die neuesten von 2026, dazu die Meldung über das aufgegebene Paket mit dem Nachfolger symfony/mailer. Dann habe ich die Angabe auf ^7.4 gelockert:

composer require guzzlehttp/guzzle:^7.4
# Upgrading guzzlehttp/guzzle (7.4.0 => 7.9.3)
# Found 9 security vulnerability advisories affecting 1 package.

Noch 9 Hinweise. Ein einfaches composer update guzzlehttp/guzzle änderte danach nichts: Nothing to modify in lock file. composer why-not guzzlehttp/guzzle 7.15.2 nannte den Grund: Die neuere Guzzle-Version verlangt guzzlehttp/promises ^2.5.1, installiert war 1.5.3. Ein Teil-Update fasst Abhängigkeiten nicht an. Erst --with-dependencies (-w), laut Dokumentation das Update auch der Abhängigkeiten der genannten Pakete, brachte den Erfolg:

composer update guzzlehttp/guzzle --with-dependencies
# Upgrading guzzlehttp/promises (1.5.3 => 2.6.0)
# Upgrading guzzlehttp/guzzle (7.9.3 => 7.16.1)
composer audit
# No security vulnerability advisories found

Zwei Dinge nehme ich daraus mit. Erstens: Ein Update-Befehl, der nichts ändert, ist keine Entwarnung. Zweitens: Wer nur die Anzahl der Funde betrachtet, übersieht, dass das Ergebnis vom Tag abhängt. Neue Hinweise erscheinen, ohne dass sich an Ihrem Code etwas ändert. Eine Prüfung gehört deshalb regelmäßig in die Pipeline und nicht nur einmal zum Projektstart.

#Aufgegebene Pakete

Ein Paket kann in seiner composer.json als aufgegeben markiert werden. Laut Schema-Dokumentation ist das entweder true oder der Name eines empfohlenen Ersatzes. Genau das zeigte der Lauf oben: Composer nannte symfony/mailer als Nachfolger von Swiftmailer.

Die aktuelle Konfigurationsdokumentation kennt dafür zwei Stellschrauben unter config.policy.abandoned: Eine Prüfung im Audit mit den Werten ignore, report und fail, und ein Blockieren bei update, require und remove. Das Blockieren ist standardmäßig aus. Ich setze es nur, wenn ein Projekt bewusst keine neuen aufgegebenen Pakete aufnehmen soll.

Der Wechsel auf einen Nachfolger ist Arbeit am Code, keine Paketpflege: Schnittstellen unterscheiden sich, Konfiguration auch. Ich plane ihn deshalb als eigenes Arbeitspaket und schreibe den Aufwand vorher auf.

#Updates in kleinen Schritten

Mein Ablauf bei einer Abhängigkeitspflege:

  1. Bestand aufnehmen. composer outdated --direct zeigt Pakete mit verfügbaren Versionen. Die Dokumentation kennzeichnet, ob die neue Version nach Semver kompatibel ist oder einen Major-Sprung bedeutet.
  2. Audit ausführen. composer audit --locked liefert die Liste der Hinweise. Sie bestimmt die Reihenfolge: Pakete mit Sicherheitshinweis zuerst.
  3. Ein Paket nach dem anderen. Jedes Update bekommt einen eigenen Commit mit der geänderten composer.lock. Geht etwas schief, lässt sich genau dieser Schritt zurücknehmen.
  4. Mit --dry-run anfangen. Die Dokumentation beschreibt die Option als Simulation, die zeigt, was geändert würde.
  5. Tests laufen lassen. Ohne Tests prüfe ich die wichtigsten Abläufe von Hand auf Staging und schreibe auf, was ich geprüft habe.
  6. Staging, dann Freigabe, dann Produktion. Auf Produktion läuft dann nur noch composer install mit der geprüften Lock-Datei.

Die Dokumentation beschreibt außerdem eine Wartezeit-Regel für frisch veröffentlichte Versionen, config.policy.cooldown.period. Ist sie gesetzt, installiert Composer bei update und require keine Version, die jünger als die Frist ist. Begründet wird sie mit Angriffen über die Lieferkette: Viele schädliche Versionen würden binnen Stunden oder Tagen erkannt und entfernt. Standardmäßig ist sie aus, und meine ausgeführten Beispiele nutzen sie nicht. Für Projekte mit vielen Paketen ist sie eine Option, die ich mit Ihnen schriftlich bespreche.

#Was das Datenschutzrecht in NRW dazu sagt

Zuständig für Unternehmen in Wuppertal ist die Landesbeauftragte für Datenschutz und Informationsfreiheit Nordrhein-Westfalen (LDI NRW). Auf ihrer Seite zu technischen und organisatorischen Maßnahmen nennt sie unter den typischen technischen Maßnahmen das „(automatisierte) Einspielen von Sicherheitsupdates“. Die DSGVO sehe eine Dokumentation aller Maßnahmen vor, sie diene dem Nachweis, dass das Unternehmen angemessene Maßnahmen umgesetzt hat.

Artikel 32 DSGVO (Verordnung (EU) 2016/679) verlangt geeignete Maßnahmen unter Berücksichtigung des Stands der Technik. Zu den genannten Punkten gehört „ein Verfahren zur regelmäßigen Überprüfung, Bewertung und Evaluierung der Wirksamkeit“ dieser Maßnahmen. Wer Personendaten in einer PHP-Anwendung verarbeitet, kann dieses Verfahren für die Abhängigkeiten konkret benennen: Audit in der Pipeline, ein fester Rhythmus für Updates, ein Protokoll der Ergebnisse.

Für kleine und mittlere Unternehmen in NRW verweist die LDI auf Digital.Sicher.NRW, das sich auf der eigenen Seite als Kompetenzzentrum und Anlaufstelle für digitale Sicherheit in diesen Unternehmen beschreibt. Ob eine rechtliche Bewertung Ihres Falls nötig ist, beantworte ich nicht: Das ist Sache Ihrer Datenschutzbeauftragten oder einer Anwaltskanzlei.

Stadthalle Wuppertal

Foto: Raimond Spekking, CC BY-SA 4.0, Wikimedia Commons.

#Was Sie schriftlich bekommen

Nach einer Abhängigkeitspflege erhalten Sie keine Zusage „alles sicher“, sondern ein Dokument, das Sie Ihrer Datenschutzbeauftragten oder Ihrem Kunden zeigen können:

  • die Ausgabe von composer audit vor und nach der Arbeit, mit Datum und Versionsstand von PHP und Composer,
  • eine Liste der aktualisierten Pakete mit alter und neuer Version und dem Commit, in dem die Änderung steht,
  • eine Liste der Pakete, die ich nicht angefasst habe, mit Grund (zum Beispiel ein Major-Sprung, der eigenes Budget braucht),
  • die aufgegebenen Pakete mit dem von Composer genannten Nachfolger und meiner Einschätzung des Aufwands,
  • die Befehle, mit denen die Prüfung in Ihrer Pipeline läuft, und die Rolle, die den Rhythmus von da an übernimmt.

Verlangt Ihr Projekt eine laufende Betreuung, beschreibe ich sie im Angebot schriftlich: Prüfung nach festem Rhythmus, Tests auf Staging, Bericht per E-Mail. Reguläre Wartung für WordPress ist auf einer eigenen Seite beschrieben: Wartung und Support Wuppertal.

#Checkliste für Ihre Anwendung

  • Liegt eine composer.lock im Repository, und ist vendor in der .gitignore?
  • Läuft auf dem Server composer install statt composer update?
  • Enthält die composer.json Angaben wie * oder >=1.0 ohne Obergrenze?
  • Stehen Pakete auf einer einzelnen festen Version, die nie wieder angefasst wurde?
  • Meldet composer audit --locked Hinweise?
  • Meldet Composer aufgegebene Pakete, und gibt es einen Nachfolger?
  • Gibt es Tests, die ein Update bemerken würden, wenn etwas bricht?
  • Steht der Rhythmus der Prüfung in Ihrer Dokumentation der technischen und organisatorischen Maßnahmen?

#So läuft ein Auftrag mit mir ab

  1. Schriftliche Anfrage. Sie beschreiben die Anwendung und was Sie wissen wollen, etwa ob ein Hinweis Ihres Hosters oder Kunden zutrifft.
  2. Rückfragen per E-Mail. Ich frage nach PHP-Version, Framework und danach, ob eine Lock-Datei existiert.
  3. Lesen des Projekts. Mit Zugang zum Repository führe ich die Prüfung aus und halte jeden Befund schriftlich fest.
  4. Umfang und Annahmen. Sie bekommen eine schriftliche Liste, was ich aktualisiere, was nicht, und welche Entscheidungen bei Ihnen liegen.
  5. Umsetzung auf Staging. Updates laufen schrittweise auf einem Branch, mit Tests und einem Commit pro Schritt.
  6. Abnahme und Übergabe. Nach Ihrer Freigabe geht die geprüfte composer.lock live. Sie erhalten die Unterlagen aus dem Abschnitt oben.

Gestaltung, Layout und Wireframes für neue Oberflächen kommen von Ihnen. Ich setze um, was Sie vorgeben.

#Was ich von Ihnen brauche

  • Lesezugriff auf das Repository oder ein Archiv des Codes, möglichst mit composer.json und composer.lock.
  • Eine Staging-Kopie der Anwendung, oder die Erlaubnis, sie aufzusetzen.
  • Die PHP-Version des Servers.
  • Eine Ansprechperson, die entscheidet, ob ein Major-Update jetzt oder später kommt.
  • Falls Sie eine haben: Ihre Dokumentation der technischen und organisatorischen Maßnahmen.

#Häufige Fragen

#Reicht composer audit als Sicherheitsprüfung?

Nein. Es meldet nur bekannte, veröffentlichte Hinweise zu Paketen, die in Ihrer composer.lock stehen. Fehler im eigenen Code, ungepatchte Serversoftware oder eine noch nicht gemeldete Lücke findet es nicht. Es ist ein günstiger erster Schritt, der in jede Pipeline gehört, kein Ersatz für eine Prüfung des Codes.

#Soll ich composer update einfach regelmäßig ausführen?

Nicht auf Produktion und nicht ohne Tests. Ein Update läuft bei mir auf einem Branch, danach laufen die Tests, dann Staging, dann Ihre Freigabe. Gerade bei Paketen mit Major-Sprung ist ein einzelner Schritt pro Paket leichter zu prüfen und zurückzunehmen als ein Gesamt-Update.

#Was tun, wenn ein Paket aufgegeben ist?

Zuerst prüfe ich, ob die Composer-Meldung einen Nachfolger nennt. Wenn ja, plane ich den Wechsel als eigenes Arbeitspaket mit Tests. Wenn nicht, schreibe ich auf, wie stark das Paket in Ihren Code eingreift, und lege mit Ihnen fest, ob ersetzt, selbst gepflegt oder bewusst weiterbenutzt wird.

#Muss die composer.lock wirklich ins Repository?

Bei einer Anwendung ja. Die Composer-Dokumentation empfiehlt es, damit CI, Produktion und alle Entwickler dieselben Versionen installieren. Der Ordner vendor gehört dagegen in die Datei .gitignore.

#Wie ist das bei einer WordPress-Seite mit Composer?

Gleiche Regeln: Lock-Datei im Repository, Audit in der Pipeline, Updates mit Tests. Für reine WordPress-Aufträge gibt es eine eigene Seite, diese hier betrifft PHP-Anwendungen, Portale und Schnittstellen.

#Was muss ich für eine erste Einschätzung mitschicken?

Die Adresse der Seite oder eine kurze Beschreibung der Anwendung, die PHP-Version, das Framework und ob eine composer.lock existiert. Zugänge sind für die erste schriftliche Einschätzung nicht nötig.

#Schreiben Sie mir

Schicken Sie mir über das Kontaktformular die Adresse Ihrer Anwendung oder eine kurze Beschreibung, das Framework, die PHP-Version, die Frage, die Sie klären wollen, und Ihren Zeitrahmen. Ich antworte schriftlich an Werktagen. Eine erste schriftliche Einschätzung von mir kostet Sie nichts. Allgemeine Informationen zu meiner PHP-Arbeit finden Sie auf der Seite PHP-Entwickler.

Brauchen Sie die Leistung: PHP-Entwickler in Wuppertal?

Beschreiben Sie Ihr Projekt per E-Mail. Antwort innerhalb von 48 Stunden.

Projekt beschreiben

Weitere WordPress-Dienste und Wissensbasis entdecken