Eine Erzählung über die Verwendung von Composer in einem WordPress-Plugin

Veröffentlicht: 2015-07-06

petersuhm Dieses Stück wurde von Gastautor Peter Suhm beigesteuert. Peter ist ein Webentwickler aus dem Land der Dänen. Er ist der Schöpfer von WP Pusher und ein großer Reisesüchtiger, der seine Arbeit immer mit sich bringt.


Neulich habe ich im WP Pusher-Blog eine Warnung über die Verwendung von Composer in WordPress-Plugins gepostet. Dieser Beitrag hat viel Aufmerksamkeit erregt und ich habe das Bedürfnis, einige Punkte zu klären, die nicht allen klar waren. Der Artikel war auch etwas technisch belastet, daher werde ich in diesem Beitrag versuchen, meinen Hauptpunkt klarer zu machen, indem ich eine einfache Erzählung verwende, um ihn zu veranschaulichen.

Eine Erzählung

Bildnachweis: Doors Open Toronto 2008 – Toronto Archives – (Lizenz)
Bildnachweis: Doors Open Toronto 2008 – Toronto Archives – (Lizenz)

Stellen wir uns für eine Weile vor, dass Sie und ich beide Plugin-Autoren sind. Wir beide haben eine großartige Idee für ein Plugin, das wir über WordPress.org verteilen möchten. Wir möchten einige Premium-Funktionen in unsere Plugins einbauen, die Benutzer der kostenlosen Version durch Eingabe eines Lizenzschlüssels freischalten können.

Wir brauchen einen Code, der diesen Prozess handhaben kann. Uns beiden ist klar, dass dieses Problem wahrscheinlich schon von jemand anderem gelöst wurde. Keiner von uns ist ein Fan davon, das Rad neu zu erfinden, also gehen wir zu Packagist und geben „Lizenzmanager“ ein. Es sieht so aus, als ob unsere Annahme gerechtfertigt war. Yoast hat bereits ein Paket, das damit umgehen kann. Wir entscheiden uns beide für einen schnellen composer require yoast/license-manager . Kinderleicht. Jetzt können wir an etwas wirklich Wichtigem arbeiten – den Kernfunktionen unserer jeweiligen Plugins.

Schneller Vorlauf, bereit zur Veröffentlichung Ihres Plugins, Sie erkennen etwas: Ihr Benutzer hat Composer nicht unbedingt zur Hand, wenn er Ihr Plugin von WordPress.org installiert, also wie werden sie den Code für den Lizenzmanager erhalten? Diese Situation ist etwas ärgerlich, denn die einzige Lösung, die Sie wirklich sehen, besteht darin, einfach das gesamte von Composer generierte vendor in Ihr Plugin zu übertragen und es auf WordPress.org zu pushen. Sie wissen, dass Composer so nicht funktionieren soll, aber was auch immer. Andere Möglichkeiten hast du eigentlich nicht.

Mittlerweile bin ich bei meinem Plugin zum selben Schluss gekommen. Fügen Sie einfach den Lizenzmanagercode hinzu und fertig.

Schneller Vorlauf noch einmal, unsere beiden Plugins leben jetzt im WordPress.org-Repository und ab und zu entscheidet sich jemand für ein Upgrade auf unsere Premium-Versionen. Alles scheint in Ordnung zu sein und wir sind beide dankbar, dass wir einfach den Code verwenden konnten, den Yoast großzügigerweise als Open Source bereitgestellt hatte, und das Rad nicht neu erfinden mussten.

Eines Tages erhalten Sie eine seltsame E-Mail. Ein Kunde erlebt ein wirklich seltsames Verhalten, wenn er versucht, Ihre Premium-Funktionen freizuschalten. Es macht keinen Sinn für Sie, weil niemand sonst dies jemals gemeldet hat. Nach stundenlangem Debuggen bitten Sie Ihren Kunden schließlich, alles andere außer Ihrem Plugin zu deaktivieren, und dann: Es funktioniert! Hmm. Ihr Plugin scheint irgendwie mit einem anderen Plugin nicht kompatibel zu sein. Mein Plugin.

Sie erkennen dies, nachdem Sie stundenlang den Quellcode aller anderen Plugins durchgesehen haben, die der Kunde installiert hatte. Wenn Sie feststellen, dass wir beide den Lizenzmanager verwenden, klingelt es. Kann das wirklich sein? Wenn ja, wie kommt es, dass keine fatal errors: cannot redeclare class wurde von PHP verursacht?

Eine Woche zuvor hatte ich die erforderliche Version des Lizenzmanagers in meinem Plugin auf die neueste Version hochgestuft, die einige (fiktive) Breaking Changes enthielt. Nach noch mehr Debugging und var_dump() 'ing stellen Sie fest, dass meine Version des Lizenzmanagers auch die Version ist, die von PHP in Ihr Plugin geladen wird. Sie finden das wirklich seltsam, weil Sie mit Composer ausdrücklich eine andere Version des Lizenzmanagers benötigt haben. Du weißt nicht wirklich, was du dagegen tun sollst.

Denn dagegen kann man eigentlich nicht viel machen.

Was ist hier passiert?

Nun, da wir alle das Problem gesehen haben, nehmen wir uns einen Moment Zeit, um durchzugehen, was tatsächlich in der Erzählung passiert ist. Zunächst einmal, warum hat PHP keinen schwerwiegenden Fehler verursacht, wenn zwei Klassen offensichtlich den gleichen Namen hatten, dass wir beide den Lizenzmanager enthielten?

Der Grund dafür ist, dass wir einen von Composer generierten Autoloader verwendet haben. Dieser Autoloader scannt die Verzeichnisstruktur unserer Abhängigkeiten und fügt dem Autoloader jede Klasse hinzu. Wenn eine Klasse bereits hinzugefügt wurde, ignoriert Composer sie. Schweigend. Ich habe ein kleines Codebeispiel geschrieben, wenn Sie es selbst sehen möchten. Es ist auf GitHub.

Warum war meine Version des Lizenzmanagers vor Ihrer enthalten?

Dies geschah, weil mein Plugin einen Namen hatte, der dazu führte, dass es vor Ihrem geladen wurde. Vielleicht werden wir in Zukunft alle unsere Plugins „Aaaaaa My Plugin“ nennen, um zuerst geladen zu werden!

Zusammenfassend ist das Hauptproblem hier also, dass wir nicht wissen, welche Version unserer Abhängigkeiten uns zu welchem ​​​​Zeitpunkt zur Verfügung stehen. Es hängt einfach von Faktoren ab, die wir als Plugin-Entwickler nicht vollständig kontrollieren können.

Ist das ein Composer-spezifisches Problem?

Nein. Das ist es wirklich nicht. WordPress hat keine Möglichkeit, mit Code von Drittanbietern in Plugins oder Themes umzugehen. Darin liegt das Problem. Der Grund, warum ich über Composer spreche, ist, dass es heutzutage viel Zugkraft gewinnt. Wenn WordPress-Entwickler Composer in über WordPress.org veröffentlichten Plugins verwenden möchten, muss dies irgendwie gelöst werden. Andernfalls sehen wir ein wahres Chaos, wenn alle Plugins miteinander inkompatibel werden, weil sie unterschiedliche Versionen verwenden. Willkommen in der Debugging-Hölle.

Was können wir dagegen tun?

Jemand, der sich darüber wirklich Sorgen gemacht und hart daran gearbeitet hat, eine mögliche Lösung zu finden, ist Coen Jacobs. Ich beschloss, mich an Coen zu wenden und ihn zu fragen, ob wir seiner Meinung nach irgendetwas dagegen tun können.

Viele Entwickler integrieren bereits Code von Drittanbietern in ihre Plugins. Ist das wirklich ein Problem?

Ja, das ist bereits ein Problem im Plugin-Ökosystem. Es wird noch schlimmer, wenn mehr Leute herausfinden, dass es eine gute Idee ist, gemeinsame Funktionen in separate Pakete zu packen. Diese Pakete können dann mit mehreren Plugins gebündelt werden und das Problem tritt immer häufiger auf. Ich habe mit ein paar Entwicklern gesprochen, die bereits durch die Debug-Hölle gegangen sind, um herauszufinden, was dieses Problem verursacht.

Würden Sie Entwicklern in Zukunft vorschlagen, den Code von Drittanbietern nicht mehr in ihre Plugins aufzunehmen?

Ich bin bei diesem Thema etwas hin- und hergerissen. Aus Entwicklersicht macht es keinen Sinn, den Leuten zu sagen, dass sie aufhören sollen, gemeinsam genutzte Pakete in ihren Plugins zu bündeln. Auf der anderen Seite möchte jeder die bestmögliche Benutzererfahrung für seine Benutzer. Es ist eine schwierige Entscheidung, um sicher zu gehen.

An dieser Stelle möchte ich die WordPress-bezogene Entwicklung vorantreiben. Ich möchte Bibliotheken freigeben und von anderen freigegebene Bibliotheken verwenden. Niemand sollte das Rad immer wieder neu erfinden. Also würde ich das Risiko eingehen, auf solche Probleme zu stoßen und die Probleme zu lösen, sobald sie auftauchen.

Das bedeutet auch, dass ich mein verdammtes Bestes tun werde, um eine langfristige Lösung für dieses Problem zu finden. Mehr Leute werden anfangen, Composer zu verwenden, mehr Leute werden Bibliotheken mit ihren Plugins bündeln. Dieses Problem wird häufiger auftreten, also ist es an der Zeit, es zu beheben.

Was können Plugin-Entwickler tun, um dieses Problem zu vermeiden?

Es gibt eine Problemumgehung, die ich bereits von einigen Leuten gesehen habe. Es kommt im Grunde darauf an, Ihre Abhängigkeit in den Namensraum Ihres Plugins zu verschieben. Danny van Kooten hat dies für eines seiner Plugins getan. Dies ist jedoch nicht ideal. Jedes Mal, wenn er seine Abhängigkeiten aktualisiert, muss er alle Dateien durchgehen und die Namespaces erneut ändern. Nun, das ist keine so große Aufgabe für eine relativ kleine Bibliothek wie Pimple, aber ein gewaltiges Unterfangen für größere Bibliotheken.

Dies ist jedoch nur mit Namespaces möglich, daher müssen Sie dafür sorgen, dass Ihr Plugin auch PHP 5.3+ erfordert. Ich werde nicht lügen, ich denke, jedes Plugin sollte früher oder später damit beginnen, aber es ist definitiv etwas, das Sie berücksichtigen müssen, wenn Sie sich dafür entscheiden.

Was wäre die ideale Lösung, falls es eine gibt?

Die ideale Situation wäre die Verwendung einer Art Abhängigkeitsmanager. Es gibt natürlich Composer, den am häufigsten verwendeten Abhängigkeitsmanager. Composer ist für die überwiegende Mehrheit der WordPress-Benutzer sehr schwer, wenn nicht unmöglich, zu verwenden. Es ist schließlich ein Entwicklerwerkzeug.

WordPress sollte dies für seine Endbenutzer einfacher machen, während es den Entwicklern dennoch ermöglicht, so ziemlich jedes gewünschte Paket zu verwenden. Aus diesem Gedanken heraus habe ich begonnen, das WordPress Composer Installer-Plugin zusammenzustellen, das die ganze harte Composer-Arbeit erledigt, während die Leute wie immer Plugins installieren. Sobald ich in der Lage bin, dies fertigzustellen, werde ich es ordnungsgemäß in den gesamten Plugin-Installationsablauf integrieren.

Jetzt kann dies vielleicht eines Tages in den Kern von WordPress integriert werden. Es ist noch ein langer Weg, aber der Proof of Concept funktioniert bereits.

Fazit

Wenn Sie bis hierher gelesen haben, zunächst einmal: Vielen Dank. Zweitens hoffe ich, dass Sie jetzt sehen, dass dies etwas ist, das schließlich zu einem Problem werden wird. Unsere aktuelle Situation ist sehr frustrierend, weil wir einfach nicht die Werkzeuge haben, die wir brauchen. Dennoch denke ich, dass es wichtig ist, dass wir weiter darüber sprechen und sicherstellen, dass wir alle als WordPress-Entwickler die potenziellen Probleme verstehen, die durch widersprüchliche Abhängigkeiten von Drittanbietern in unserem Code verursacht werden.

Abschließend möchte ich noch einmal erwähnen, dass dies kein Composer-Problem ist. Es ist ein WordPress-Problem.