Verschiedene Methoden zum Debuggen von PHP-Code

Diese Woche wurde ich um Hilfe bei der Einrichtung von Xdebug mit PhpStorm auf einem Linux-Laptop in Verbindung mit Docker gebeten. Darüber schreibe ich vielleicht in einem kommenden Blogbeitrag. Heute möchte ich mich aber auf verschiedene Methoden zum Debuggen von PHP-Code konzentrieren.

1. echo, print_r, var_dump – der schnelle, aber hässliche Weg

Wer schon einmal etwas in PHP entwickelt hat, ist wohl nicht um eine der „Ausgabefunktionen“ herumgekommen. Mit echo kannst du einen generischen Wert wie einen String oder eine Zahl ausgeben. Für Arrays und Objekte verwendest du eher print_r oder var_dump.

Vorteile:

  • Einfach: Die Methoden können einfach verwenden werden. Du musst nichts installieren, um sie nutzen zu können.
  • Schneller Einblick: Wenn du einfach nur den Wert an einer bestimmten Stelle ausgeben möchtest, ist es mit den Funktionen sehr einfach, den aktuellen Wert an dieser Stelle auszugeben.

Nachteile:

  • Ausgabe-Einschränkungen: Die Methoden sind eher einfach. Du erhältst nur den Wert dieser einen Variable, aber keinen „Kontext“. Da die Ausgabe oft in ein HTML-Dokument gerendert wird, musst du sie möglicherweise in ein <pre>-Tag für Arrays/Objekte einbetten oder sie im Quellcode anzeigen lassen.
  • Störend: Wenn du die Variablen ausgibst, dann tust du das möglicherweise beim Rendern eines Templates. Das bedeutet, dass dein Layout/Design verzerrt wird.
  • Unsicher: Wenn du diese Methode auf einer Live-Website verwendest, dann ist die Ausgabe für alle sichtbar. Das sieht nicht nur wie ein Fehler aus, es kann auch ein Sicherheitsrisiko darstellen, wenn der Inhalt der zu debuggenden Daten nicht sichtbar sein sollte.
  • Aufräumen erforderlich: Selbst wenn du diese Methode nur beim lokalen Entwickeln verwendest, musst du daran denken, den Code wieder zu entfernen, bevor du ihn hochlädst oder du einen Commit und Push in eine Versionskontrolle machst. Es passiert recht schnell, dass man einige Zeilen übersieht, die dann auf einer Live-Website landen.

2. error_log, file_put_contents – Ausgabe in eine Datei

Anstatt die Debug-Ausgabe direkt auf dem Bildschirm auszugeben, könntest du sie in eine Datei schreiben. Dies hat einige Vorteile, aber auch einige Nachteile:

Vorteile:

  • Trennung der Zuständigkeiten: Wenn du die Debug-Informationen in eine Datei schreiben lässt, dann hälst du den Anwendungscode frei von Debug-Ausgaben. Du könntest sogar deine eigene Debugging-Funktion als Wrapper für die error_log oder file_put_contents Funktionen einführen und innerhalb dieser Funktion prüfen, ob der „Debug-Modus“ aktiv ist.
  • Dauerhafte Speicherung: Wenn du diesen „Debug-Modus“ aktiviert hast, kannst du die Daten über einen längeren Zeitraum in der Datei speichern und diese Datei dann später auf die möglichen Fehler hin überprüfen. Es ermöglicht dir auch das Debuggen von Anfragen von anderen Personen, womit du möglicherweise Probleme finden kannst, die du selbst nicht „siehst“.
  • Keine störende Ausgabe: Deine Ausgabe auf der Website bleibt sauber, da alle Debug-Daten nur die Datei geschrieben werden.

Nachteile:

  • Manuelle Überprüfung: Du erhältst die Debug-Informationen nicht sofort. Wenn du dies auf einer Live-Website ausführst, siehst du möglicherweise sogar die Debug-Informationen einer anderen Person. Mithilfe des tail Befehls kannst du die Datei aber fast in „Echtzeit“ debuggen.
  • Schwieriger zu debuggen: Wenn du eine gemeinsame Debug-Datei für alle Funktionen verwendest, erhältst du alle Debug-Daten ohne jeglichen „Kontext“. Wenn du also die Datei/Zeile einer bestimmten Meldung identifizieren möchtest, musst du sie vielleicht noch __FILE__ und __LINE__ voranstellen und zusätzlich auch Datum/Uhrzeit voranstellen, damit du weißt, wann der Eintrag geschrieben wurde.
  • Overhead: Das Loggen von Daten in eine Datei kann die Leistung der Website beeinträchtigen, insbesondere wenn du eine große Menge Daten debuggst. Du solltest auch die Dateigröße der Debug-Datei von Zeit zu Zeit überprüfen und sicherstellen, dass der Debug-Modus nur dann deaktiviert ist, wenn du ihn wirklich braucht, da du sonst leicht den gesamten verbleibenden Speicherplatz auf deinem Server mit einer riesigen Protokolldatei füllen kannst.
  • Sicherheitsrisiko: Ja, auch die Verwendung einer Debug-Datei kann ein Sicherheitsrisiko darstellen, falls diese öffentlich zugänglich ist. Wenn sie allerdings nicht öffentlich zugänglich ist, dann ist das Debuggen mit einer Datei wieder schwieriger, du den Inhalt dann nur über ein Terminal oder durch Herunterladen einsehen kannst. WordPress beispielsweise speichert die debug.log Datei im wp-content Ordner und macht sie für alle aufrufbar. Du kannst aber den Pfad anpassen, um den direkten Zugriff zu verhindern.

Debug-Plugins – das Beste aus beiden Varianten bekommen

Für WordPress verwende ich normalerweise immer das Query Monitor-Plugin. Dieses Plugin bietet mehrere Actions zum Debuggen von Variablen. Eine davon ist die qm/debug Action.

Vorteile:

  • Keine direkte Ausgabe: Durch die Verwendung dieser Action gibst du die Debug-Daten nicht auf der Seite aus, die Website wird also nicht verzerrt dargestellt.
  • Sicherheit: Du siehst die Debug-Daten von Query Monitor (und dem Hook) normalerweise nur denn, wenn du ein Administrator der Website bist. Aber du kannst es sogar (mithilfe eines Cookies) verwenden, wenn du ausgeloggt bist.
  • Keine Debug-Datei erforderlich: Es sendet die Debug-Daten mit der Response und speichert keine Datei auf dem Server ab. Damit hast du nicht die Nachteile der vorherigen Methode.

Nachteile:

  • Debug-Code in deinem Anwendungscode: Wie bei den anderen Methoden musst du immer noch Code zum Debuggen in deinen Anwendungscode schreiben. Du würdest diesen Code dann auch auf einer Live-Website haben oder einem Repository haben. Das sollte für „unveröffentlichten“ Code in Ordnung sein, aber du möchtest ihn lieber nicht in einem Plugin/Theme veröffentlichen. Bevor du also eine neue Version des Plugins/Themes veröffentlichst, müsstest du den Debug-Code wieder entfernen.
  • Kann keine defekten Seiten debuggen: Da diese Debugging-Methode das Query Monitor-Plugin erfordert, kannst keinen schwerwiegenden Fehler debuggen, der den Query Monitor daran hindert angezeigt zu werden.
  • Du siehst nur deine eigenen Fehler: Du kannst diese Methode nicht verwenden, um Probleme zu debuggen, die eine andere Person mit deiner Website hat, und du möchtest der anderen Person wahrscheinlich auch nicht die Berechtigung geben, Query Monitor selbst zu verwenden.

Xdebug – die nächste Stufe des Debuggens

Wenn du noch nie von Xdebug gehört hast und/oder es noch nie verwendet hast: verwende es direkt, nachdem du diesen Blogbeitrag gelesen hast! Für mich ist es das beste Tool, um komplexe Probleme zu debuggen. Xdebug ist eine PHP-Erweiterung, die installiert und aktiviert werden muss. Du benötigst auch eine IDE wie PhpStorm oder VS Code, um es zu verwenden, aber dann kann es dir wirklich helfen, diese schwer zu debuggenden Probleme zu finden.

Vorteile:

  • Kein zusätzlicher Code erforderlich: Anstatt Debugging-Funktionen in deinen Code zu schreiben, setzt du einfach einen „Breakpoint“ in deiner IDE in einer bestimmten Zeile.
  • Du kannst alles debuggen: Sobald ein Breakpoint erreicht ist, kannst du jede Variable debuggen! Du bist also nicht auf eine einzelne Variable beschränkt, sondern du kannst den Wert aller Variablen einsehen. Du kannst auch den „Aufrufstapel“ sehen, also jede Funktion, die vor dem Erreichen dieses Punktes aufgerufen wurde. Du kannst auch zu diesen Funktionen zurückgehen und die Parameter untersuchen, mit denen sie aufgerufen wurden.
  • Nur bestimmte Fälle untersuchen: Angenommen, dein Code bricht nur in Fällen ab, in denen eine Variable einen bestimmten Wert hat. In diesem Fall kannst du einen bedingten Breakpoint verwenden, der nur anhält, wenn diese Bedingung erfüllt ist.
  • „Was-wäre-wenn“: Du hast also ein Problem mit einer Variable und ihrem Wert gefunden und nun fragst du dich, ob der Code mit einem anderen Wert funktionieren würde? Wenn du an einem Breakpoint bist, kannst du den aktuellen Wert einer Variable überschreiben und dann fortsetzen, um zu sehen, was in diesem Fall passieren würde.

Nachteile:

  • Schwierige Einrichtung: Wenn du Xdebug noch nie zuvor verwendet hast, könnte es schwierig sein, es einzurichten. Du musst die PHP-Erweiterung auf dem Rechner, auf dem du den Code ausführst, installieren und aktivieren und deine IDE konfigurieren. Wenn du es mit Docker verwendest, musst du auch sicherstellen, dass der PHP-Container mit deiner IDE „kommunizieren“ kann. Obwohl es viel einfacher geworden ist und PhpStorm heutzutage (fast) keine Konfiguration mehr benötigt, könnte es schwierig sein, es beim ersten Mal zum Laufen zu bringen. Ich verwende es normalerweise in Kombination mit DDEV und weiß jetzt, wie ich es schnell zum Laufen bringen kann. Aber deine Konfiguration könnte eine andere seit.
  • Könnte deinen Request abbrechen: Da du den Request beim Debuggen „anhältst“, könnte es möglich sein, dass deine Website nicht mehr angezeigt wird, wenn du den Code hast durchlaufen lassen. Das ist normalerweise der Fall, wenn du nginx als Webserver verwendest. Du erhältst dann einen Error 500, weil die Anfrage an das „PHP-Backend“ abgelaufen ist.
  • Auf Live-Umgebungen nicht wirklich verwendbar: Xdebug ist super für die Entwicklung in einer lokalen Umgebung, aber es nicht das beste Tool für den Einsatz auf einer Live-Website. Xdebug hat einen großen Einfluss auf die Performance. Da Xdebug mit deiner IDE „kommunizieren“ muss, könnte es auch schwierig bis unmöglich sein, eine Konfiguration zu finden, die mit deiner IDE und einer Live-Site funktioniert.

Fazit

Es gibt verschiedene Methoden zum Debuggen von PHP-Code, und alle von ihnen haben ihre Vor- und Nachteile – sogar mehr, als ich in diesem Blogbeitrag erwähnt habe. In einigen Fällen reicht ein schnelles Debuggen mit echo aus. Aber es gab in der Vergangenheit einige Probleme, die ich ohne die Hilfe von Xdebug niemals gefunden hätte. Daher empfehle ich dringend, eine Konfiguration zu finden, die für dich funktioniert.

Ich habe einige Leute nach ihren Debugging-Methoden gefragt. Etwa 40% verwenden häufig Methode 1, etwa 5% Methode 2 und „nur“ 55% haben schonmal Xdebug benutzt. Ich hoffe, dass ich die anderen 45% auch endlich davon zu überzeugen, Xdebug als ihr Debugging-Tool zu benutzen.

Und was ist mit dir? Hast du Xdebug schon mal benutzt? Verwendest du andere Methoden, die ich nicht erwähnt habe und die für dich gut funktionieren? Dann hinterlasse bitte einen Kommentar.

WordCamp Leipzig 2023 – Kleiner, aber genauso großartig!

Gestern habe ich das WordCamp Leipzig besucht. Es was das erste WordCamp vor Ort in Deutschland seit 2019. Es war ein WordCamp, aber in mancher Hinsicht auch speziell.

Anreise nach Leipzig mit dem Zug

Wenn ich normalerweise ein WordCamp besuche, dann muss ich Züge (oder Flüge) und eine Unterkunft buchen. Für dieses WordCamp konnte ich meine Wohnung kurz nach 7 Uhr verlassen, 10min zum Bahnhof laufen, 1:40h den ICE nehmen, am Hauptbahnhof Leipzig ein kleines Frühstück und Kaffee mitnehmen, in die Tram steigen und knapp 2h nach Verlassen der Wohnung schon beim WordCamp sein. Es war also fast wie ein lokales WordCamp in Berlin.

Treffen der lokalen Communtiy

Dieses WordCamp wurde von Anfang an für die Community aus Leipzig ausgerichtet. Einige Teilnehmende sind von weiter her angereist, mindestens einer sogar aus dem Ausland. Aber dennoch hatte ich die Chance, neue Community-Mitglieder kennenzulernen. Einige davon kannte ich schon aus dem WP Meetup Berlin, allerdings nur per Zoom.

Ein Zeitplan mit nur einem Track und eingeladenen Vortragenden

Normalerweise schreibe ich immer über die ausgesuchten Vorträge, die ich auf einem WordCamp besucht habe, aber dieses Mal was es einfacher, da es nur einen Track gab: ich habe alle besucht 🙂

Alle Vortragenden wurden vom Organisationsteam eingeladen. Einige Themen waren nicht unbedingt solche, die ich mir auf einem WordCamp ansehen würde, aber mir haben alle gefallen. Ein paar gingen mehr in die Tiefe und haben Wissen vermittelt, andere waren allgemeiner.

Maja aus der Berliner Community hat auch einen Vortrag zu Barrierefreiheit gegeben. Auch wenn ich viele Dinge schon kannte, so waren doch einige der neuen Regelungen, die 2025 in Kraft treten, noch neu für mich:

Click here to display content from Twitter.
Erfahre mehr in der Datenschutzerklärung von X.

Kein Mittagessen!

Das WordCamp Leipzig wollte „so minimalistisch wie möglich“ sein. Daher wurden wir zur Mittagspause alle gebeten, uns selbst etwas zum Essen zu suchen. Der Veranstaltungsort war aber so gut gelegen, dass im Umkreis von 100 m sehr viele Angebote für jeden Geschmack dabei waren. Ich habe mich einer Gruppe angeschlossen, die (vegetarische) Burger essen gegangen ist. Wir haben dabei viel über Plugins, Einstellungen/Optionen und andere Entwicklungsthemen gesprochen.

Es war aber nicht so, als hätte sich das Organisationsteam nicht um uns gekümmert. Es gab kostenlose (alkoholfreie) Getränke und mit Mate und Cola war man dann auf für das Nachmittagsprogramm noch fit genug. Am Nachmittag gab es auch noch Kuchen und Muffins. Zwischen den Vorträgen sind wir meistens rausgegangen, um ein wenig Sauerstoff zu tanken und zu reden.

Ein langer kurzer Tag

Wenn man 7 Vorträge ab Stück hört, und keine Chance hat etwas anderes zu tun, wie mit Sponsoren zu sprechen, wie auf größeren WordCamps, dann fühlt sich so ein Tag schon lang an. Aber er war auch wiederum recht kurz, denn plötzlich war schon der letzte Vortrag vorbei und es war Zeit für die Verabschiedung.

Darin wurde dann dem Organisationsteam (5 Personen), sowie den globalen und lokalen Sponsoren gedankt. Das Team hat dann auch angekündigt, dass es auch 2024 wieder ein WordCamp Leipzig geben wird:

Click here to display content from Twitter.
Erfahre mehr in der Datenschutzerklärung von X.

Die Organizer haben dann alle gebeten zu gehen, und sich einfach abzusprechen, wer im Anschluss noch woanders hingehen möchte. Aber währen wir schon draußen standen hat uns ein Organizer mitgeteilt, dass wir doch noch länger bleiben könnten. Und da die Getränke schon bezahlt und noch nicht leer waren, man jetzt auch auf eigene Kosten Bier und ähnliches kaufen konnte und jemand vorgeschlagen hat Pizza zu bestellen, sind wir geblieben und es gab eine „Afterparty“:

Click here to display content from Twitter.
Erfahre mehr in der Datenschutzerklärung von X.

Ich bin noch etwa 4h geblieben und habe mit anderen über verschiedene Themen gesprochen. Jemand konnte mir auch endlich mal erklären, wie Instagram funktioniert ?

Zeit nach Hause zu fahren

Ich habe wieder eine Tram zum Hauptbahnhof genommen, und musste zum Glück nicht ganz alleine fahren. Heiko wohnt fast bei mir um die Ecke und hatte den gleichen Zug gebucht. Kurz vor Mitternacht war ich dann nach diesem WordCamp endlich zu Hause, was sich wirklich wie ein lokales angefühlt hat.

War es wirklich ein WordCamp?

Letzte Woche hat WP Tavern über die neuen WordCamp Formate geschrieben, mit denen das Community-Team experimentieren möchte. Das WordCamp Leipzig war eines der Events, die darin erwähnt wurden. Manche haben dann auf Twitter darüber diskutiert, ob es denn wirklich ein WordCamp sei oder nicht doch eher ein Meetup.

Meiner Meinung nach war es sehr wohl ein WordCamp. Ich habe schon andere WordCamp besucht, die nur einen Track hatten und auch solche, bei denen alle Vortragenden eingeladen wurden. Kein Mittagessen zu haben, was für mich kein Problem, denn so hatte man die Chance die anderen kennenzulernen und alle konnten das Essen finden, das sie gerne essen.

Also was genau hätten Leute erwartet, um es als WordCamp zu bezeichnen und nicht als „Ganztagesmeetup“?

Ein neues Format für mehr Communitys

Ich habe bereits erfahren, dass auch die Britische Community darüber nachdenkt, ein ähnliches Event zu veranstalten. Dort wird es wohl mehr Teilnehmende und auch Mittagsessen geben, aber ebenfalls maximal eine kleine Afterparty.

Dies war zumal, mit Ausnahme des „inoffiziellen“ WordCamp Jena 2019, das erste WordCamp im Osten von Deutschland. Zu sehen, dass die Organisatoren bereits für 2024 planen, ist ein tolles Zeichen! Und da wir gerade vom Organisationsteam sprechen, sie haben einen tollen Job gemacht. Danke also an alle im Team!

Würde ich auch ein solches Event veranstalten?

Ich habe über so etwas für Berlin nachgedacht. Tatsächlich hatten wir das ja für 2015 geplant, es wurde dann aber doch wieder ein größeres und „traditionelles“ WordCamp. Aktuell habe ich keine Pläne in diesem oder nächsten Jahr ein WordCamp zu organisieren. Ich würde dann aber wohl mal eines der neuen Formate ausprobieren. Bevor ich aber ein WordCamp organisiere, möchte ich einen do_action: Charity Hackathon in Berlin organisieren!

Vierzehn Jahre Bloggen und ein bisschen Wehmut

Heute ist es mal wieder so weit. Mein Blog hat Geburtstag. Angefangen hat es am 21. Juni 2009, der Grund dafür war vor allem, dass ich zwei Tage zuvor mein erstes Plugin veröffentlicht hatte.

Schließung meines ersten Plugins ?

Nachdem dieses Plugin zuletzt aber nur noch 10+ aktive Installationen hatte und auch seit langem nicht mehr gepflegt wurde, habe ich es dann gestern, 14 Jahre nach der ersten Version, endgültig schließen lassen.

Aber keine Angst, ich werde heute nicht auch noch meinen Blog endgültig abschalten, ganz im Gegenteil!

Zahlen, Zahlen, Zahlen!

Einen neuen Besucherrekord hat es nicht gegeben. Aber dennoch ist ein Block auf die Zahlen der vergangenen 12 Monate interessant. Während auf der deutschen Seite etwa 9,8% mehr Besuche stattfanden, waren es auf der englischen Seite 181% mehr. Und nachdem ich früher etwa einen Anteil von 15-20% bei den englischen Seitenaufrufen hatte sind es nun durch diesen starken Zuwachs ca. 53,4% und somit lese mehr Menschen meinem Blog auf Englisch als auf Deutsch! Es hat sich also gelohnt, weiter alle zwei Wochen einen Beitrag in beiden Sprachen zu schreiben.

Top3 im letzten Jahr

  1. Fatale Fehler in WordPress mit PHP 8+ und einer fehlerhaften Übersetzung
  2. Formatierten Quellcode mit Syntaxhervorhebung in Word einfügen
  3. Direkte Downloads mit dem „download“ Attribute

Es gibt einen neuen Platz 1 in den Top3 und es ist ein Artikel, den ich erst am Dezember 2022 veröffentlicht habe. In also nicht einmal einem halben Jahr hat er mehr Aufrufe gehabt, als die alte Nummer 1, die zwei Plätze einbüßen musste. Dafür ist der drittstärkste Beitrag wieder auf dem zweiten Platz gelandet. Im Vorjahr hatten sie die Plätze gewechselt, nun geht es wieder zurück, mit noch größerem Abstand als letztes Jahr.

Kein neues Theme

Vor einem Jahr hatte ich groß angekündigt, dass ich das aktuelle Theme einmal komplett neu als FSE-Theme programmieren wollte. Leider ist aus dem Vorhaben nichts geworden. Vermutlich dachte ich, dass ich ohne die Orga-Arbeit für das WCEU dafür mehr Zeit hätte, aber so ein Jobwechsel und ein erneuter Umzug in eine neue Wohnung verschlingen dann eben auch Zeit und Energie. Daher möchte ich an dieser Stelle nicht wieder etwas versprechen, was ich vielleicht in den nächsten 12 Monaten wieder nicht halten kann. 😅

WordCamps sind wieder da!

Auch wenn ich aktuell nicht in der Orga eines WordCamps dabei bin, so habe ich doch bereits drei vor Ort dieses Jahr besucht. Übernächstes Wochenende bin ich dann beim WordCamp Leipzig, was versucht, ein anderes und sehr reduziertes Format zu zeigen. Im August geht es dann zum WordCamp US, im September (sehr wahrscheinlich) zum WordCamp London und schließlich im Oktober zum großen WordCamp Deutschland. Ihr könnt euch also wieder auf einige Blogbeiträge mit Berichten dazu freuen. Und im nächsten Jahr bin ich (hoffentlich) wieder beim WordCamp Europe in Turin dabei, entweder nur als Attendee, oder aber das erste Mal als (normaler) Speaker. Um wie immer den Blogbeitrag mit einem Video abzuschließen, könnt ihr hier das Video mit der Ankündigung sehen:

Click here to display content from YouTube.
Erfahre mehr in der Datenschutzerklärung von YouTube.

WordCamp Europe 2023 – Eine andere Perspektive auf das größte WordPress Event

Ich schreibe diesen Blogbeitrag, während ich noch immer in Griechenland bin. Dieses Jahr habe ich das WordCamp in einer anderen Rolle erlebt. Nachdem ich 2017 dem Organisationsteam beigetreten und bis letztes Jahr alle Veranstaltungen vor Ort mitorganisiert habe, bin ich zum Event in Athen in einer anderen Rolle gereist.

Meine erste Reise nach Griechenland

Wie schon so oft in den vergangenen Jahren hatte ich auch dieses mal wieder die Gelegenheit ein neues Land durch ein WordCamp kennenzulernen. Es was meine erste Reise nach Griechenland und somit natürlich auch mein erster Besuch von Athen. Begonnen habe ich die Reise am Freitag vor zwei Wochen. Wir haben ein wenig die Sehenswürdigkeiten der Stadt angesehen. Der Besuch der Akropolis was natürlich Pflicht und die Erfahrung war es auf jeden Fall wert. Aber Athen hat sehr viel mehr zu bieten. Nicht nur historische Plätze, sondern auch tolles Essen.

Remote Arbeiten

Seit ich am 1. Oktober zu Inpsyde gewechselt bin, habe ich die Freiheit, von überall aus zu arbeiten. Und da Athen nur 1 Stunde Zeitunterschied zu Berlin habe, konnte ich recht einfach von Montag bis Mittwoch arbeiten. Andere Inpsyder kamen am Mittwoch an und wir haben uns dann abends zu einem schönen Abendessen getroffen.

Donnerstag: Contributor Day

Genau wie in den vorherigen Ausgaben des WordCamp Europe begann das Event mit dem Contributor Day. Ich hatte am Morgen noch ein paar Dinge zu erledigen und war daher erst vor Ort, als sich die Gruppen bereits gefunden hatten. Ich bin an den „Meta + WordCamp“ Tisch gegangen und habe versucht ein wenig an dem Ticket zu arbeiten, das ich beim WordCamp Asia im Februar angefangen hatte. Aber da ich auch zu einem Panel eingeladen wurde, habe ich auch etwas Zeit damit verbracht, um mit zwei anderen Panelists an den Themen zu arbeiten. Direkt um Anschluss musste ich auch schon wieder gehen, weil wir das Hotel wechseln mussten. Es war also insgesamt kein so effektiver Contrbutor Day, wie ich es mir gewünscht hatte.

Am Abend war ich dann als Speaker zu „Social“ eingeladen. Eine tolle Gelegenheit, um alte Freude zu treffen und neue zu machen.

Freitag: der erste Konferenztag

Obwohl ich etwa 10min zu spät war, habe ich die Opening Remarks nicht verpasst. Wendie, die Leiterin des Volunteer-Teams, hat als Einhorn verkleidet das Publikum etwas aufgeheizt:

Click here to display content from Twitter.
Erfahre mehr in der Datenschutzerklärung von X.

Direkt nach den Opening Remarks bin ich in den ersten Vortrag gegangen.

Test instead of guessing – generate more leads through growth hacking

Dieser Vortrag wurde von meiner Kollegin Viola gehalten. Selbst wenn ich mit dem Thema in meinem Job nicht viel zu tun habe, war es doch ein faszinierendes Thema und Viola hatte es perfekt vorbereitet. Man konnte spüren, dass sie sehr für das Thema brennt und es war kaum zu glauben, dass dies ihr erster Vortrag auf einem WCEU (oder anderen Event dieser Größe) war.

Click here to display content from Twitter.
Erfahre mehr in der Datenschutzerklärung von X.

Nach diesem ersten Slot habe ich mich erneut mit den anderen Panelists getroffen und wir haben die Themen für Samstag gesammelt, über die wir sprechen wollten, und auch Antworten auf Fragen vorbereitet, die vielleicht aufkommen werden. Nach dem Mittagessen bin ich dann in eine Runde von drei Lightning-Talks zum Themenkomplex AI gegangen.

Take your WordPress website to another level using AI translation

Dario hat eine kurze Einführung in das Problem von Übersetzungen gegeben und wieso es wichtig ist, eine Website in mehrere Sprachen zu übersetzen, um potenziell mehr Menschen anzusprechen. Er hat über die verschiednene Lösungen zur Übersetzung einer WordPress-Website gesprochen und wieso es für diese wichtig sein wird, die verschiedenen Überserzungs-AIs zu integrieren.

Innovating inclusion: harnessing AI for accessibility

Im zweiten Lightning-Talk hat Sarah den Fokus auf Barrierefreiheit gelegt und gezeigt, wie eine AI helfen kann, diese zu verbessern. Sie hat ein paar Tools vorgestellt, die automatische Tests auf Barrierefreiheit für eure Website durchführen können. Sie hat auch einen Dienst gesprochen, der ein WordPress-Plugin zur Verfügung stellt, mit der man über ein „Overlay“ die Barrierefreiheit verbessern könnte. Ich persönlich empfehle solche Lösungen habe nicht, da sie oft die eigentlichen Probleme nicht wirklich beheben können.

Content creation with the help of AI

Der finale Lightning-Talk dieser Runde wurde vom deutschen Community-Mitglied Silvio gehalten. Man hat gemerkt, dass es sein erste WCEU-Vortrag war, denn er war sehr nervös. Er hat aber eine sehr interessante Fallstudie gezeigt, bei der er einmal einen Menschen und einmal eine AI zu den gleichen Themen Beiträge schreiben ließ. Dabei war die Conversion Rate der AI etwas besser als die des Menschen. Ich hoffe, das wird kein Trend.

Women and non-binary folx of WordPress

Nach diesen Vorträgen in Track 1 bin ich dann in den Track 2 geeilt. Dort habe ich mit ein spannendes Panel von Menschen aus der WordPress Community angesehen, die über ihre persönlichen Erfahrungen als Frauen oder nichtbinäre Personen in der Community gesprochen haben. Es gab eine paar sehr spannende Themen, eine davon zum Thema Fragen nach Vorträgen. Es wurde empfohlen, dass diese optional sein sollten. Ich mag diese Idee wirklich sehr und bin gespannt, ob einige zukünftige WordCamp damit experimentieren werden.

Click here to display content from Twitter.
Erfahre mehr in der Datenschutzerklärung von X.

You say you support women in tech

Den letzten Vortrag des Tages hat Amy gehalten. Darin hat sie sehr persönliche Erfahrungen als alleinerziehende Mutter, Frau in der IT und Opfer von häuslicher Gewalt erzählt. Die hat viele gute Tipps gegeben, was Unternehmen tun können, wenn sie Frauen in der IT wirklich unterstützen wollen. Das ist genau dir Art der Vorträge, die ich auf einem WordCamp Europe sehen will.

Am Abend war ich dann zu mehreren Parties eingeladen, habe es aber nur zur „Pride“ Party geschafft, die von Yoast mitorganisiert wurde. Schon in Bangkok hatte ich daran teilgenommen.

Samstag: der zweite Konferenztag

Den zweiten Tag habe ich etwas später begonnen und die Zeit vor dem Panel genutzt, um ein paar Sponsoren zu besuchen und mich mit mehr Leuten zu treffen. Dann war es an der Zeit mich für mein erstes Panel (meinen ersten Talk) auf einem WordCamp Europe.

WCEU Globals: future of WCEU

Ich durfte die Bühne mit Lesley, Taeke, Rocío, Moncho und Tess, den vorherigen Global Leads von WCEU 2020 – 2022, teilen. Leider konnte Jonas nicht mit dabei sein in Athen. Wir haben über verschiedene Aspekte der Organisation eines Events dieser Größe gesprochen und was wir uns für die Zukunft wünschen würden. Ich weiß noch immer nicht, ob ich in Zukunft erneut dem Orga-Team beitreten würde, aber ich bin sehr offen dafür als Mentor für zukünftige Generationen von Organizern zur Verfügung zu stehen, wie alle anderen Global Leads auch.

Click here to display content from Twitter.
Erfahre mehr in der Datenschutzerklärung von X.

Direkt nach dem Panel sind wir dann alle rausgegangen für das obligatorische Familienfoto. Seht nur, wie viele Menschen dieses Jahr dabei waren – und es rechtzeitig auf das Foto geschafft haben 😉

Click here to display content from Twitter.
Erfahre mehr in der Datenschutzerklärung von X.

Nach dem Mittagessen habe ich vor allem mit mehr Teilnehmenden gesprochen und weitere Sponsoren besucht. Ich habe es nur irgendwie fast verpasst, Swag mitzunehmen. Dann war auch schon die Zeit für die letzte Session.

Variations on a theme: 20 years of WordPress

Der Tradition eines WordCamp Europe folgend gab es auch wieder einen Talk von Matt. Er wurde auf der Bühne begleitet von Josepha und Matías. Die Themen waren die Phasen 3 und 4 von Gutenberg sowie der Community Summit. Es wurden aber auch einige faszinierende Dinge gezeigt, auf die wir uns in Zukunft freuen können. Im Anschluss war auch wieder viel Zeit für Fragen. Bei der Frage zu Mehrsprachigkeit, welche erst in Phase 4 dran ist, wurde das Publikum gefragt, wer nicht Englisch als erste Sprache spricht und es fühlte sich an, als würden alle die Hand heben. Matt hat uns auch aufgefordert „learn AI deeply“, na so ungefähr zumindest 😉 Er hat auch fast gespoilert, wo das WCEU nächstes Jahr stattfinden wird ?

Click here to display content from Twitter.
Erfahre mehr in der Datenschutzerklärung von X.

Closing remarks

Aber natürlich ist die Verkündung für das nächste Jahr etwas, dass ein WordCamp Europe immer abschließt. Zuvor wurde aber das Organisatoinsteam auf die Bühne gebeten, gefolgt von allen Volunteers. Dann kam endlich der Moment, auf den alle gewartet hatten, die nächste Stadt wurde verkündet. Hier ist das Video dazu SPOILER ALERT! Lest nicht den Text zum Tweet 😉

Click here to display content from Twitter.
Erfahre mehr in der Datenschutzerklärung von X.

Wir sehen uns also nächstes Jahr in Turin, Italien. Ich hatte bereits das Vergnügen, die Stadt durch ihr lokales WordCamp 2017 kennenzulernen. Eine schöne Stadt mit tollem Essen! Ihr solltet also auf jeden Fall auch dabei sein!

Die After-Party

Da ich am nächsten Tag sehr früh aufstehen musste, um eine Fähre zu erreichen, konnte ich nicht allzu lange auf der After-Party bleiben. Zuvor habe ich mich aber mit den anderen Inpsydern auf ein schnelles Abendessen getroffen, bevor ich mich dann etwa 90min in die Menge begeben habe. Die Venue hat mich sehr stark an Sofia erinnert. Drinnen war es echt laut, weshalb viele Teilnehmende den Platz direkt vor der Venue bevölkert und die warmen Abendtemperaturen genossen haben.

Ein wenig Urlaub

Da dies meine erste Reise nach Griechenland war, und ich ohnehin für ein WordCamp Europe immer mindestens eine volle Woche einplane, habe ich noch eine weiter Woche in Griechenland dran gehängt. Wir haben also am Sonntag eine Fähre nach Ikaria genommen, und sind dann am Freitag nach Kos gefahren. Heute sind wir dann zurück nach Berlin geflogen, voller schöner Erinnerungen.

Ein anderes WordCamp Europe

Das war mein erstes WordCamp Europe, bei dem ich nicht mitorganisiert habe, seit einer ganzen Weile und es hat sich ziemlich anders angefühlt. Ich bin der Tradition folgend den Kreislauf Local Lead -> Global Lead -> Speaker durchlaufen und kann mich nun zur Ruhe setzen. Ich werde auch dem nächsten Orga-Team nicht beitreten, da aktuell andere Dinge in meinem Leben wichtig sind, bis das nächste WordCamp Europe stattfindet. Ich bin mir noch nicht einmal sicher, ob ich dabei sein kann. Aber falls es klappt, dann habe ich vielleicht endlich den Mut, mich mit einem richtigen Vortrag zu bewerben, oder zumindest als Volunteer zu melden, was ich bisher nur einmal 2016 gemacht habe. Was also auch immer die Zukunft bringen mag, wir sehen und in Turin … oder wo immer es 2025 stattfinden wird ?

20 Jahre WordPress – Meine persönliche Reise

Normalerweise schreibe ich immer am 20. Juni einen Beitrag, um den Geburtstag dieses Blogs zu feiern. Aber heute möchte ich die Gelegenheit nutzen und #WP20 zu feiern, den 20 Geburtstag unserer geliebten Open-Source-Software.

Kein Teenager mehr

Mit 20 Jahren ist WordPress nun ein erwachsenes Stück Software. Es hat einmal klein angefangen und brachte am Anfang nur knapp 250KB auf die Waage. Heute ist es fast 100 mal schwerer. Aber es ist auch auf viele Weisen gereift.

Ich möchte aber nicht zu viel über die Geschichte des CMS sprechen. Wenn euch interessiert, wie es sich über die Jahre verändert hat, dann kann ich euch die Seite DisplayWP ans Herz legen, die ich diese Woche entdeckt habe.

WordPress und Ich

Stattdessen möchte ich also auf meinen persönliche Weg mit WordPress eingehen. Die erste Version, die ich genutzt habe, was (sehr wahrscheinlich) die Version 2.7.3 im Juni 2009. Damals war ich in meinen ersten Job nach dem Studium und ein Kollege wollte WordPress verwenden, um Termine anzuzeigen. Also selbst damals habe ich es nicht als klassischen Blog verwendet. Da es aber noch keine Custom-Post-Types gab, die erst mit Version 2.9 eingeführt wurden, haben wir stattdessen Beiträge für die Termine verwendet.

Mein Kollege brauchte eine Funktion, die nicht im Core vorhanden war, also schrieb ich mein erstes Plugin, veröffentlichte es, und begann selbst mit dem Bloggen.

Die Community

Mein erstes WordCamp habe ich 2010 hier in Berlin besucht. Dort habe ich auch andere Menschen getroffen, die es verwendeten und die „Stars“, zu denen ich aufschaute und von denen ich so viel gelernt hatte.

Nach dem WordCamp Köln wurden die ersten deutschen Meetups gegründet. Für mich am nächsten war das in Potsam, dass ich zu zweiten Termin im Dezember 2011 zum ersten Mal besuchte.

Da für 2012 kein WordCamp in Deutschland geplant war, hat die Potsdamer Meetup Gruppe kurzerhand die WP Camps 2012 und 2013 organisiert.

Ebenfalls 2014 habe ich das erste internationale WordCamp besucht und auch das allererste WordCamp Europe in Leiden.

Nach diesem Event war es klar für mich, dass ich mehr mit WordPress machen wollte. Also habe ich zwei Jahre später den Job gewechselt und bei VCAT angefangen, einer Agentur in Potsdam. Eines der Mitglieder der Meetup Gruppe (mittlerweile einer der Organisatoren), ist mitbegründet dieser Agentur. Man könnte also sagen, dass ich meinen zweiten Job durch die WordPress Community bekommen habe. Ende 2015 hat die Berliner Meetup Gruppe (die ich seit 2014 organisiere) dann das erste „offizielle“ WordCamp Berlin organisiert.

Springen wir ins Jahr 2017, in dem ich ein weiteres WordCamp Berlin organisiert habe. Gleichzeitig bin ich auch dem Orga-Team des WordCamp Europe beigetreten. Zwei Events gleichzeitig zu organisieren, eines davon als Lead Organizer, war aber wirklich keine gute Idee, so viel kann ich euch sagen. ?

Ein Grund für den Beitritt zum WCEU Orga-Team war immer, dass ich das WordCamp Europe nach Deutschland bringen wollte, was uns dann auch 2019 gelungen ist.

Dann hat die Pandemie die Communit getroffen und die Arbeitswelt für viele von uns auf den Kopf gestellt. Mir hat sie gezeigt, dass ich doch von zu Hause und/oder unterwegs arbeiten kann. Daher bin ich dann im Oktober zu Inpsyde gewechselt, der Agentur, die die ersten deutschen WordCamps organisiert hat und maßgeblich in die Gründung der deutschen Community 2004 involviert war, nur ein Jahr nach der Veröffentlichung der ersten Version von WordPress.

In ca. zwei Wochen halte ich dann meinen ersten Vortrag auf dem WordCamp Europe, wo ich dann auch wieder viele alte und neue Freunde treffen werde.

Wie WordPress mein Leben verändert hat

Nachdem ich aus meiner Heimatstadt nach Berlin gezogen bin, hatte ich hier nicht viele Freunde. Durch die Community, und meine beiden Jobs, habe ich aber viele tolle Menschen kennengelernt. Manche davon sind sogar zu meinem besten Freunden geworden, auch abseits von WordPress Events.

Durch die Teilnahme an WordCamps hatte ich auch die Gelegenheit viele neue Orte zu besuchen. Diese (internationalen) Orte/Länder, habe ich zum ersten Mal besucht, weil ich ein WordCamp besucht habe:

  • Prag
  • Norrköpping
  • Bilbao
  • Zürich
  • Mailand
  • Brighton
  • Turin
  • Zagreb
  • Las Palmas
  • Helsinki
  • Philadelphia
  • Nashville
  • Leiden
  • Sofia
  • Sevilla
  • Belgrad
  • Porto
  • Bangkok

Ich habe also ca. 10 Länder und einen neuen Kontinent zum ersten Mal durch ein WordCamp besucht. Jedes Mal habe ich Menschen getroffen, die ich schon kannte, aber viel wichtiger, auch Menschen, die ich noch nicht kannte, oder mit denen ich nur seit vielen Jahren online kommunizier habe.

Danke WordPress und alles Gute zum Geburtstag!

Ich weiß nicht, wie mein Leben ohne WordPress verlaufen wäre. Aber ich bin sehr dankbar für die Möglichkeiten, die sich mir geboten haben. Und ich fühle immer auch geehrt, dass ich mich als Teil einer großen globalen Community sehen kann.

Ich hoffe, dass noch 20 weiter Jahre (und mehr) folgen werden und kann es kaum erwarten zu sehen, wie WordPress mit 40+ aussehen wird, so wie ich. ?

Die Beiträge zum Blog-Geburtstag beende ich meisten mit einem Video und heute möchte ich eine Botschaft von Mike Little mit euch teilen, einem der beiden Mitbegründer von WordPress, und einen der nettesten Menschen aus der Community, den ich bisher treffen durfte:

Click here to display content from Twitter.
Erfahre mehr in der Datenschutzerklärung von X.

Verschachtelte Funktionen in PHP und warum du sie vermeiden solltest!

Diese Woche habe ich den Code einer Website überprüft. Die Website verwendete einige Code-Schnipse und in einem davon habe ich eine verschachtelte PHP-Funktion gefunden. Der Code funktionierte nicht wie erwartet. Nicht wegen der verschachtelten Funktion, aber er hat mich auf die Idee für diesen Blogbeitrag gebracht. Ich kann den ursprünglichen Code nicht teilen, aber ich hoffe, ich kann euch anhand eines Beispiels zeigen, wie verschachtelte Funktionen funktionieren und warum ihr sie wahrscheinlich nicht verwenden solltet.

Was ist eine verschachtelte Funktion?

Eine verschachtelte Funktion in PHP ist eine Funktion, die im Inhalt einer anderen Funktion deklariert wird. Wir könnten sie als „äußere Funktion“ und „innere Funktion“ oder „verschachtelte Funktion“ bezeichnen. Hier ist ein Beispiel für eine solche verschachtelte Funktion:

function multiplyAllByTwo( $array ) {
	function multiplyByTwo( $value ) {
		return $value * 2;
	}

	return array_map( 'multiplyByTwo', $array );
}

Wir haben eine Funktion, um ein Array zu verarbeiten und alle Werte darin mit 2 zu multiplizieren. Durch die Verwendung einer Funktion könnten wir „potenziell“ dasselbe für mehrere Arrays machen. Innerhalb dieser Funktion deklarieren wir eine andere Hilfsfunktion, die einen gegebenen Wert mit 2 multipliziert. Das ist die verschachtelte Funktion. Sie wird dann mit array_map() verwendet, die sie dann auf jeden Eintrag des Arrays anwendet. Wenn wir also ein Array übergeben, erhalten wir das Array zurück, in dem alle Werte mit 2 multipliziert wurden.

$inputArray = [ 1, 2, 3, 4, 5 ];
$resultArray = multiplyAllByTwo( $inputArray );
print_r( $resultArray );
/*
Array
(
	[0] => 2
    [1] => 4
    [2] => 6
    [3] => 8
    [4] => 10
)
*/

Das ist toll, also wo liegt das Problem? Versuchen wir einfach mal, das resultierende Array erneut zu multiplizieren:

$inputArray   = [ 1, 2, 3, 4, 5 ];
$resultArray  = multiplyAllByTwo( $inputArray );
$resultArray2 = multiplyAllByTwo( $resultArray );
print_r( $resultArray );
print_r( $resultArray2 );

Was erwarten nach den beiden Aufrufen? Ein zweites Array, bei dem alle Werte erneut mit 2 multipliziert wurden, richtig? Aber was erhalten wir stattdessen?

PHP Fatal error:  Cannot redeclare multiplyByTwo() ...

Wenn die Funktion ein zweites Mal aufgerufen wird, erhalten wir einen schwerwiegenden Fehler, da die Funktion nicht erneut mit demselben Namen deklariert werden kann. Eine verschachtelte Funktion funktioniert also nur für eine „äußere Funktion“, die nur einmal ausgeführt wird. Was könnten wir also stattdessen tun?

Verwende keine verschachtelte Funktion

Der einfachste Weg wäre es, die verschachtelte Funktion aus der anderen Funktion zu entfernen und sie im globalen Namespace zu deklarieren.

function multiplyAllByTwo( $array ) {
	return array_map( 'multiplyByTwo', $array );
}

function multiplyByTwo( $value ) {
	return $value * 2;
}

Jetzt können die (vorher) äußere Funktion zweimal aufrufen:

$inputArray = [ 1, 2, 3, 4, 5 ];
$resultArray1 = multiplyAllByTwo( $inputArray );
$resultArray2 = multiplyAllByTwo( $resultArray1 );
print_r( $resultArray1 );
print_r( $resultArray2 );
/*
Array
(
	[0] => 2
    [1] => 4
    [2] => 6
    [3] => 8
    [4] => 10
)
Array
(
	[0] => 4
    [1] => 8
    [2] => 12
    [3] => 16
    [4] => 20
)
*/

Jetzt erhalten wir das gewünschte Ergebnis. Aber wir füllen auch den globalen Namespace mit vielen Funktionen und müssen dabei sicherstellen, dass wir für diese verschiedenen Hilfsfunktionen nicht denselben Funktionsnamen verwenden. Als Alternative kannst du die Funktion auch einer Variable zuweisen und diese anstelle des Funktionsnamen-Strings verwenden. Aber dazu müsstest du diese Variable wieder innerhalb der äußeren Funktion zuweisen, da sie sonst nicht verfügbar wäre. Oder du müsstest die Variable innerhalb der Funktion mit dem globalen Schlüsselwort verfügbar machen. Beide Lösungen sind nicht wirklich schön, und deshalb möchte ich nicht einmal Code-Snippets dafür zeigen ?

Also, wenn du nicht wirklich eine global deklarierte Funktion benötigst, wie kannst du es dann sonst lösen? Es gibt einen anderen Weg.

Verwende eine anonyme Funktion

Eine anonyme Funktion wird oft in Kombination mit Funktionen wie array_map() und ähnlichen Funktionen verwendet. Unser Code würde dann so aussehen:

function multiplyAllByTwo( $array ) {
	return array_map( function ( $value ) {
		return $value * 2;
	}, $array );
}

In diesem Beispiel deklarieren wir die Funktion in dem Moment, in dem wir sie benötigen. Dadurch entfällt auch die Notwendigkeit, einen schönen Namen dafür zu finden, und wir wissen alle, dass das Benennen von Dingen eine der „zwei schwierigen Dinge in der Programmierung“ ist ?

Mit PHP 7.4 und höher kannst du sogar eine schöne kleine Arrow-Function verwenden, die es dir ermöglicht, einen Einzeiler für dieses Snippet zu schreiben:

function multiplyAllByTwo( $array ) {
	return array_map( fn( $value ) => $value * 2, $array );
}

Sieht gut aus, oder?

Fazit: Wann sollte man was verwenden?

Ich würde empfehlen, niemals eine verschachtelte Funktion zu verwenden! Obwohl das in anderen Programmiersprachen häufig gemacht wird, kann es in PHP leicht zu schwerwiegenden Fehlern und Problemen beim Testen und Debuggen führen.

Wenn es sein kann, dass du die Logik der „inneren Funktion“ für mehrere „äußere Funktionen“ benötigst, dann deklariere die Funktion immer mit einem Namen, entweder im globalen Namespace oder in einer PHP-Klasse.

Wenn du diese Logik nur für diese spezifische „äußere Funktion“ benötigst oder sie wirklich sehr einfach ist, wie in diesem Beispiel, kannst du eine anonyme Funktion oder sogar eine Arrow-Function verwenden.

Fehlende Sidebar-Widgets nach der Migration – was war passiert?

Ich schreibe diesen Blogbeitrag auf meinem neuen Server. Der alte wird in etwa zwei Stunden abgeschaltet. Da ich einige WordPress-Seiten und eine Matomo-Instanz hoste, war die Migration schon eine größere Aufgabe.

Ich bin bei der Migration meinem „5 Minuten Migration-Prozess“ gefolgt und alles lief so weit wie erwartet. Als ich dann aber meinem Blog nach der DNS-Umstellung aufgerufen hatte, haben auf einmal zwei Text-Widgets gefehlt. Was war passiert?

Emojis ?

Seit einer ganzen Weile unterstützt WordPress nativ Emojis. Man kann sie einfach in einen Blogbeitrag einfügen und WordPress zeigt sie an. In der Vergangenheit wurde dazu noch ein SVG-Sprite verwendet. Aber da moderne Betriebssysteme und Browser diese nun nativ unterstützen, ist das nicht mehr notwendig.

Aber wieso hat die Verwendung von Emojis bei nach der Migration zu einem Fehler geführt? Auf dem alten Server habe ich MySQL 8 verwendet und auf dem neuen ist es MariaDB 10. Beim Export der Datenbank habe ich einfach wie immer wp db export ausgeführt. Aber nach dem Import waren dann UTF-8-Multibyte-Zeichen defekt. Anstelle von Emojis wurden nur einige ?? Symbole angezeigt.

Vermutlich hat dies die unserialize() Funktion WordPress, die WordPress verwendet gestört, und das ganze Widget war kaputt. Dies hat dann dazu geführt, dass die ersten beiden Text-Widgets nicht mehr angezeigt wurden, obwohl sie in der Datenbank vorhanden waren.

Exportieren der Datenbank mit utf8mb4

Nachdem ich den Fehler gefunden und ein wenig recherchiert habe, bin ich auf ein WP-CLI Issue zu diesem Effekt gestoßen. Ich konnte anschließend durch das Hinzufügen eines Flags für das Standard-Charset einen funktionierenden Dump exportieren:

$ wp db export --default-character-set=utf8mb4

Das Importieren dieses SQL-Dumps hat den Fehler dann behoben, und die beiden Text-Widgets waren wieder da. Und es wurden auch wieder alle Emojis in den Blogbeiträgen angezeigt.

Fazit: Immer die WP-CLI aktualisieren!

Nachdem ich die Datenbank erfolgreich reparieren konnte, wollte ich wissen, wieso das (noch immer) passiert. Das Issue gibt an, dass der Fehler im db-command behoben und mit Version 2.5.0 der WP-CLI veröffentlicht wurde. Allerdings habe ich auf dem Server noch die Version 2.4.0 verwendet, die diesen Fix noch nicht enthielt.

Nach einem Update auf die aktuelle Version (2.7.1), musste ich das Flag nicht mehr angeben, und habe dennoch einen korrekten Export inklusive Emojis und andere utf8mb4 Zeichen erhalten.

Bevor ihr also wichtige Wartungsaufgaben durchführt, solltet ihr besser immer die WP-CLI auf die neueste Version aktualisieren, um nicht in Fehler zu rennen, die schon lange behoben sind und die ihr vielleicht nicht sofort bemerkt. Hätte ich den Fehler erst in ein paar Tagen/Wochen bemerkt, dann wäre es sehr schwierig geworden, die Datenbank zu reparieren/synchronisieren.

Umgang mit Zeitzonen – wie man es nicht macht!

Letzte Woche hatte ich mit einem interessanten Problem zu tun. Die Seite nutzte einen Custom-Post-Type für Webinare. Wenn man angemeldet war, dann sollte man ein paar Minuten vor dem Beginn des Webinars einen „Beitreten“ Button sehen. Es gab hierzu im Backend auch eine Einstellung für die Anzahl der Minuten, um die Anzeige des Buttons vor dem Beginn des Webinars zu steuern.

Aus irgendeinen Grund hat das aber nicht funktioniert. Da wir bereits ein anderes Problem in dem Plugin in Bezug auf Zeitberechnungen gefunden hatten, habe ich die Zeit erst einmal auf 300 Minuten vor dem Event gesetzt, was das Problem erst einmal löste, denn das Webinar war bereits seit 5 Minuten am Laufen. Aber was genau was eigentlich schiefgegangen. Bei der Suche nach dem eigentlich Fehler bin auf einen „cleveren Code“ gestoßen.

Analyse der Daten

Das Plugin verwendete Daten von einer externen API. Diese API hat mehrere Felder zurückgegeben, die dann in Postmeta gespeichert wurden. Das sind einige der verwendeten Felder:

+---------+-------------------------------+------------------------------+
| post_id | meta_key                      | meta_value                   |
+---------+-------------------------------+------------------------------+
| 1234567 | webinar_created_by            | api                          |
| 1234567 | event_id                      | 12345                        |
| ...     | ...                           | ...                          |
| 1234567 | to_date                       | Montag, 27. März 2023        |
| 1234567 | date                          | Montag, 27. März 2023        |
| 1234567 | date_en                       | 27 Mar 2023                  |
| 1234567 | to_date_en                    | 27 Mar 2023                  |
| 1234567 | start_time                    | 19:00:00                     |
| 1234567 | end_time                      | 20:45:00                     |
| 1234567 | time_zone                     | Mitteleuropäische Sommerzeit |
| ...     | ...                           | ...                          |
+---------+-------------------------------+------------------------------+

Könnt ihr etwas erkennen? Hm, vermutlich nicht, da ihr diesen Beitrag auf Deutsch lest. Aber die Daten sind teilweise übersetzt. So wird als Zeitzone der String „Mitteleuropäische Sommerzeit“ verwendet und nicht der englische Name „Central European Summer Time“ (CEST, GMT+2). Die Zeit ist also der UTC zwei Stunden voraus. Genau deshalb hatte ich auch auf die Schnelle einen Wert größer als 120 Minuten gesetzt, um sicherzugehen, dass ein solches potenzielles Problem dadurch gelöst würde. Aber wenn die Zeitzone doch eigentlich richtig angegeben ist, wieso kam es dann zu einem Fehler?

Umwandlung des Zeitzonen-Strings

In diesem Plugin gab es eine Funktion, die Zeitzonen-Strings in eine UTC-Differenz umwandelt. Die Funktion sieht in etwa wie folgt aus:

function get_timezone_mapping( $name = '' ) {
	$mapping = [
		// ...
		'Central Time' => '-6',
		'Central Standard Time' => '-6',
		'Canada Central Standard Time' => '-6',
		// ...
		'Portugal Winter Time' => '+0',
		'India Standard Time' => '+05:30',
		// ...
		'Восточноевропейское время' => '+2',
		'Eastern European Summer Time (Athens)' => '+3',
		'Eastern European Summer Time' => '+3',
		// ...
		'北京时间' => '+8',
		'台北時間' => '+8',
		'Seoul Time' => '+9',
		'日本時間' => '+9',
	];

	if ( ! empty( $name ) ) {
		if ( ! empty( $mapping[ $name ] ) ) {
			return $mapping[ $name ];
		} else {
			return false;
		}
	}

	return $mapping;
}

Man übergibt also einen String für eine Zeitzone und erhält einen String mit der Differenz zu UTC. Für einige Zeitzonen gab es mehrere Varianten und teilweise auch Übersetzungen der Bezeichnungen. Nur unsere „Mitteleuropäische Sommerzeit“ war nicht dabei, weshalb die Funktion in diesem Fall dann false zurücklieferte.

Der Zeitpunkt, an dem Dinge kaputtgingen

Nun wurde die Funktion und ihr Rückgabewert verwendet, um ein Date Objekt zu erzeugen. Es wurde dann mit der aktuellen Zeit (des Servers) verglichen. Der Code sah in etwa sie folgt auch (vereinfacht):

// Data dynamically queried from the database.
$webinar_data = [
	'time_zone' => 'Mitteleuropäische Sommerzeit',
	'date_en' => '27 Mar 2023',
	'start_time' => '19:00:00',
];
// ...
$timezone = $webinar_data['timezone'];
$start_date = $webinar_data['date_en'];
$start_time = $webinar_data['start_time'];
// ...
$timezone_mapping = get_timezone_mapping( $timezone );
$date_timezone = ! empty( $timezone_mapping ) && ! is_array( $timezone_mapping ) ? new DateTimeZone( $timezone_mapping ) : null;

$current_datetime = new DateTime( 'now', $date_timezone );
$start_datetime = $start_date ? new DateTime( $start_date . ' ' . $start_time, $date_timezone ) : null;
// ...
$pre_buffer_minutes = empty($minutes) ? 15 : absint($minutes);
// ...
// Subtract the buffer from the webinar's starting date & time.
$start_datetime->sub( new DateInterval( "PT{$pre_buffer_minutes}M" ) );
$is_within_time = $current_datetime->getTimestamp() >= $start_datetime->getTimestamp();

Lasst und das mal runterbrechen und versuchen den Fehler zu finden. Die Zeitzone des Webinars wurde an die Funktion get_timezone_mapping() übergeben, aber da es den String „Mitteleuropäische Sommerzeit“ nicht zuordnen konnte, gab sie false zurück, womit dann im Ergebnis null als Wert für $date_timezone in Zeile 13 herauskam. Diese Zeitzone wurde dann für beide Aufrufe von new Date() verwendet. Aber was passiert hier nun? Schauen wir uns dazu die beiden resultierenden Date Objekte einmal an, und welche Zeit sie repräsentieren, wenn die Aufrufe um „19:00“ Uhr (Serverzeit) passieren:

$current_datetime = (new DateTime('now', null))->format('Y-m-d H:i:s');
// 2023-03-27 17:00:00
$start_datetime = (new DateTime('27 Mar 2023 19:00:00', null))->format('Y-m-d H:i:s');
// 2023-03-27 19:00:00

Da für das zweite Date Objekt $start_datetime ein gültiger „Datumsstring“ verwendet wird, erstellt PHP ein Objekt mit exakt dieser Zeit und ignoriert dabei die Zeitzone. Das erste Date Obbjekt $current_datetime hingegen verwenden den String now und hat ebenfalls kein gültiges DateTimeZone als zweiten Parameter. Wenn ein solcher fehlt, dann verwendet PHP immer UTC als Zeitzone. Also selbst, wenn der Server (oder das WordPress-System) auf „Central European Summer Time“ läuft, wird PHP dennoch UTC verwenden. Damit erhalten wir dann die 2-Stunden-Differenz zur gewüschten Zeit. Schließlich wir dann die $is_within_time Variable false sein, bis die $pre_buffer_minutes plus der 2-Stunden-Differenz erreicht sind.

Wie geht man mit Zeitzonen besser um?

Wie ihr an dem Code sehen könnt, ist der Umgang mit Zeitzonen auf diese Weise eine schlechte Idee. Vor allem dann, wenn die Zeitzonene-Strings eventuell auch noch übersetzt sind. Man kann unmöglich eine Liste mit allen möglichen Varianten pflegen. Also was sollte man stattdessen tun?

Ich würde empfehlen einen „Industriestandard“ zu verwenden, der aich die Zeitzone verwendet, wenn man eine Uhrzeit und ein Datum definiert. In der Tabelle am Beginn der Blogbeitrags siehr man selbst für das Datum zwei Schreibweisen: „Montag, 27. März 2023“ und „27 Mar 2023“. Der erste ist dabei auch noch übersetzt. Durch das Aufteilen der Werte für Zeit, Datum und Zeitzonen auf meherer Felder muss man diese dann wieder zusammensetzen (wie in Zeile 16), in daraus dann ein „Datumsobjekt“ in verschiedenen Programmiersprachen erstellen zu können. Aber wieso verwenden wir nicht ein Format wie das folgende, das alle Teile bereits kombiniert?

$webinar_start = 'Mon, 27 Mar 2023 19:00:00 +0200';

Dieser Strings enthält alle Teile für Zeit, Datum und Zeitzone. Das ist auch der Wert den man erhält, wenn man das $date->format('r') Ausgabeformat wählt. Es folgt den Standards RFC 2822/RFC 5322. Wenn jemand nun eure API verwendet, können sie dann aus diesem String ein „Datumsobjekt“ erstellen und davon dann Zeit, Datum, oder andere Werte auslesen.

Fazit

Der Umgang mit Zeitzonen ist bei der Programmierung oft nicht einfach. Wenn man dann auch noch mit verschiednen Zeitzonen zu tun hat, wird es nochmals schwerer. Ihr könnt euch naütrlich dennoch dafür entscheiden, die einzelnen Werte für Zeit/Datum auch separat anzubieten, aber bitte bieete auch einen String wie oben beschrieben an. Und solltet ihr ech entscheiden dies nicht zu tun, dann übersetzt bitte die Namen von Zeitzonen, Monatsnamen oder ähnlichem nicht auch noch, da es sonst zu dem erwähnten (und manchmal schwer zu lösenden) Problem führen kann.

Für dieses spezielle Plugin habe ich bisher noch keine Lösung gefunden. Wenn die API einen solchen String in Zukunft nicht anbietet, dann wird mir wohl nichts anderes übrig bleiben als das statische Array in der Funktion immer wieder mit weiteren (übersetzten) Zeitzonen.String zu erweitern. Ich werde mit aber nie sicher sein können, dass nicht eines Tages ein neuer Wert dazu kommt, den ich noch nicht habe, und der dann wieder zu diesem Problem führt.

Mein CloudFest Hackathon 2023 Erfahrungsbericht

Letztes Wochenende bin ich in den Europa-Park in Rust gefahren, um an meinem zweiten CloudFest Hackathon teilzunehmen. Das diesjährige Event hatte 11 verschiedene Projekte, 7 davon waren WordPress-Projekte (einige andere hatten nur lose mit WordPress zu tun). Im letzten Jahr habe ich das Team des Pluginkollektiv dabei unterstützt, am beliebten Antispam Bee Plugin zu arbeiten. Dieses Jahr hat das Team dann an Statify, einem datenschutzfreundlichen Statistik-Plugin gearbeitet.

Click here to display content from Twitter.
Erfahre mehr in der Datenschutzerklärung von X.

Kleine Schritte zu einem neuen und besseren Plugin

Für das Antispam Bee Projekt haben wir letztes das gesamte Plugin neu geschrieben, mit dem Ziel, eine neue Hauptversion zu veröffentlichen. Diese neue Version ist nun in der Alpha-Phase, also selbst ein Jahr nach dem Event, noch immer nicht fertig. Für Statify hatte unser Teamlead Florian Brinkmann im Vorfeld einige Issues auf GitHub ausgesucht, an denen er mit dem Team arbeiten wollte. Manche davon waren sogenannte „low-hanging fruits“, andere wiederum größere Issues und Feature-Requests.

Ein vermeintlich einfaches Ticket

Wir hatten ein paar Teammitglieder, die ganz neu dabei waren, an einem Projekt mitzuwirken und haben versucht für sie einige einfache Issues zu finden. Eines davon hatte den Namen „Show title instead of permalink“ und klang daher recht einfach. Das Ticket war fast 5 Jahre alt, mit einer konstruktiven Diskussion. Es gab auch schon einen PR mit einer einzeiligen Änderung, um einen Teil des Problems zu lösen. Das Issue sollte also einfach zu lösen sein, richtig? Nun, wie sich herausstellte, war es nicht ganz so einfach. Es gab einen Grund, wieso dieses Ticket seit 2018 noch nicht gelöst wurde. Nachdem wir in der Gruppe ausführlich darüber gesprochen hatten, haben wir einige Sonderfälle identifiziert, die eine genauere Planung erforderten.

Erarbeiten einer Lösung und Einführung neuer Möglichkeiten

Nachdem wir mehrere mögliche Lösungswege diskutiert hatten und zu einigen davon ein „proof of concept“ hatten, wurde recht deutlich, dass es die beste Lösung wäre, wenn wir den aktuellen Beitragstitel zum Zeitpunkt des Trackings des Seitenaufrufs durch Statify speichern würden. Da die eigene Tabelle von Statify recht einfach ist, gab es zwei mögliche Lösungswege:

  1. Hinzufügen einer neuen Spalte zur Tabelle
  2. Hinzufügen einer statifymeta Tabelle zum Speichern dies Titels

Wir haben uns für den zweiten Ansatz entschieden. Auch wenn es vielleicht ein wenig zu umfangreiche für ein so kleines Feature wirkt, so kann es die neue Tabelle Statify (und erweiternden Plugins) ermöglichen, zu jedem Eintrag zusätzliche Informationen zu speichern, ohne jedes Mal die Tabelle anpassen zu müssen. Zusätzlich macht es auch die Aktualisierung von Statify einfacher, dass die Änderungen von existierenden Tabellen auf manchen Umgebungen zu Problemen führen kann.

Onboarding neuer Contributoren

Ich muss zugeben, dass ich nicht sehr viel Code geschrieben habe. Ich habe nur eine kleine UX-Verbesserung beigetragen. Stattdessen habe ich aber anderen bei ihren Contributions geholfen. Ein Teammitglied, das sonst eher keinen Code schreibt, hat seine erste Contribution gemacht und der PR wurde auch direkt geprüft und gemerged. Ein anderes Teammitglied hat an dem Beitragstitel Issue gearbeitet und kannte sich mit einigen Dingen noch nicht so gut aus. Nachdem wir zwei Tage an dem Issue gearbeitet hatten, war es an der Zeit, den aktuellen Stand zu commiten. Erst dann hat er mir erzählt, dass er bisher noch nicht mit Git gearbeitet hat, also habe ich ihm eine kleine Einführung gegeben und er konnte einen Commit in seinen Fork machen. Zu diesem Zeitpunkt haben wir dann festgestellt, dass in der Zwischenzeit andere Dinge geändert wurden, die zu Konflikten führten. Also konnte er auch die Behebung davon ein wenig lernen. Jetzt muss der neue Code noch getestet werden, bevor er dann gemerged werden kann. Da dieses Issue, und einige andere, an denen wir gearbeitet haben, recht groß waren, werden wir wohl eine neue Hauptversion von Statify veröffentlichen, die alle Bugfixes und neuen Features des Hackathons enthalten wird.

Ein Event, das man besuchen sollte!

Ich kann leider nicht so viele Details zu den anderen Teams geben. Ich würde euch aber empfehlen, euch mal den Hashtag #CFHack2023 anzusehen, um einen besseren Eindruck vom Event zu bekommen. Für mich war es wieder ein tolles Event! Nicht nur der „hacking“ Teil, sondern auch die soziale Komponente. Es gab einge offizielle Parties und spaßige Aktionen, wie etwa das Mario Kart Turniert am Sonntagabend.

Nach der Verkündung der Gewinner-Teams der verschiedenen Kategorien, hat sich die deutsche Communtiy zu einem sponaten Meta-Meetup getroffen. Darin haben Meetup-Organizer der verschiedenen Städte ihre Erfahrungen und Ideen zu deren Meetups geteilt. Wir planen ein solches Meeting nun häufiger zu haben:

Click here to display content from Twitter.
Erfahre mehr in der Datenschutzerklärung von X.

Das CloudFest

Am Nachmittag gab es denn mit dem „WordPress Day“ den offiziellen Startschuss zum CloudFest. Das Haupt-Event, das am Dienstag startete, ist hauptsächlich ein „Industrie-Event“. Beim WordPress Day ging es aber in verschiedenen Vorträgen um Themen rund um das WordPress-Ökosystem, auch wenn es nicht unbedingt die typischen Themen waren, die man sonst auf einem WordCamp sehen würde. Einige davon waren eher Produkt-Präsentationen.

Am Abend fand das „Come2Gather in the Streets“ Event am Haupteingang des Europa-Parks statt. Neben Essensständen und Getränken gab es auch Livemusik. Ich hatte dann auch endlich die Gelegenheit, mit einigen Menschen zu sprechen, die in den Tagen zuvor genauso beschäftigt waren wie ich, oder die gerade erst zum Haupt-Event angereist waren.

Leider musste ich am Dienstag schon um 11 Uhr abreisen und konnte mir daher keine Sessions ansehen. Ich habe es gerade so geschafft, ein wenig durch die „Cloud Fair“, den Ausstellungsbereich, zu schlendern und mit einigen Sponsoren zu sprechen. Ich hatte auch keine Zeit, ein paar Achterbahnen zu fahren, die nur für Teilnehmende offen hatte. Im letzten Jahr hatte ich dazu aber viel Zeit.

Fazit

Auch wenn ich etwas „enttäuscht“ war, dass ich selbst nicht so viel programmiert habe, wie im letzten Jahr, hat es mir doch sehr viel Spaß gemacht, viele neue Menschen an die Open-Source-Contribution heranzuführen. Alle waren sehr aufgeregt und motiviert. Sie wollen auch in Zukunft weiter mitwirken.

Wenn nichts dazwischen kommt, dann bin ich auch im nächsten Jahr wieder gerne dabei. Vielleicht schaffe ich es dann auch, ein Projekt einzureichen. Für das eine Thema, das ich dieses Jahr einreichen wollte, hatte ich nicht genügend Zeit zur Vorbereitung. Wenn ihr selbst noch nie contributed habt, dann kann ich euch sehr empfehlen, einen Hackathon oder ein WordCamp mit einem Contributor-Day in eurer Nähe zu finden. Ihr lernt dabei neue Dinge und neue Menschen kennen!

Verwendung von Git zur Versionierung deiner Server-Konfigurations-Dateien

Ich habe vor kurzem einen neuen Webserver geholt. Auf diesem neuen Server experimentiere ich ein wenig mit OpenLiteSpeed, was ich noch nie zuvor verwendet habe. Es bringt eine eigens Admin-Dashboard mit, um den Server zu verwalten. Aber alles wird in Konfigurations-Dateien gespeichert.

Manchmal möchte oder muss man diese Dateien aber manuell anpassen. Wenn nicht die von OpenLiteSpeed, dann aber vielleicht die SQL oder PHP Konfiguration. Wenn man dann nicht genau weiß, was man tut, macht man schnell Dinge kaputt.

Versionierung deiner Konfigurations-Dateien

Aus diesem Grund habe ich angefangen, meine Konfigurations-Dateien unter Versionsverwaltung zu stellen. Das hat einige Vorteile:

  • Du kannst Dinge ausprobieren und rückgängig machen, wenn etwas kaputt geht
  • Du hast ein „Backup“ deiner Konfiguration
  • Du kannst die gleichen/ähnliche Konfigurations-Dateien auf allen deinen Servern verwenden und die synchronisieren
  • Du siehst alle Änderungen, die von anderen Prozessen gemacht wurden – beispielsweise nach einem Update oder durch ein Konfigurations-Tool

Nur die wichtigsten Dateien versionieren und solche mit sensitiven Informationen ignorieren

Auf vielen Linux-Servern befinden sich alle Konfigurations-Dateien im /etc Ordner. Du könntest jetzt also auf die Idee kommen, einfach den gesamten Ordner zu versionieren. Aber das ist eventuell keine gute Idee, denn einige Dateien enthalten sensitive Daten und man kann auch schnell etwas kaputt machen. Ich habe beispielsweise einmal aus Versehen die /etc/passwd Datei gelöscht, was keine gute Idee war. ?

Ignorieren von nginx Konfigurations-Dateien

Auf meinem alten Server habe ich also nur die Ordner /etc/php und /etc/nginx in zwei separaten Git-Repositories versioniert. Für die nginx Konfigurationen habe ich dann die folgende .gitignore Datei verwendet:

# /etc/nginx/.gitignore
*param*.pem
sites-enabled/
modules-enabled/
modules-available/

In der zweiten Zeile ignoriere ich die dhparam-4096.pem Datei, welche für einen besseren Diffie-Hellman-Schlüssel verwendet wird. Ich ignoriere auch die *-enabled Ordner, die nur Symlinks auf die *-available enthalten. Ihr könnt diese aber auch versionieren, wenn ihr tracken wollt, welche Sites und Modules enabled wurden. Der modules-available Ordner hatte für mich auch keinen größeren Wert, weshalb ich ihn ausgelassen habe.

Ignorieren von OpenLiteSpeed Konfigurations-Dateien

Auf dem neuen Server bin ich immer noch dabei herauszufinden, wie die Konfigurations-Dateien strukturiert sind. Die OpenLiteSpeed Dateien befinden sich im Ordner /usr/local/lsws und aktuell sieht meine .gitignore wie folgt aus:

# /usr/local/lsws/.gitignore
# Ignore all files by default but decent into subfolders
*
!*/

# Allow just some files and subfolders
!.gitignore
!/conf/**
!/lsphp*/**
!/php/**

# Still ignore some files and folders in those subfolders
*.conf.bak
*.conf.dpkg
*.conf.txt
*.conf0
*.conf0,v
*.properties0
*.properties0,v
/lsphp*/bin/
/lsphp*/include/
/lsphp*/lib/
/lsphp*/share/man/

Da der /usr/local/lsws Order nicht nur die Konfiguration, sondern auch Binärdateien und Logfiles enthält, ignoriere ich erst einmal alle Dateien und Ordner. Dann füge ich nur die Ordner hinzu, die Konfigurations-Dateien enthalten, die ich versionieren möchte.

Nachdem ich einige Pakete aktualisiert habe, gab es viele „Backup-Konfigurations-Dateien“, also habe ich auch alle mit diesen Dateiendungen, in den zuvor erlaubten Ordner, ignoriert.

Ich werde diese Ignoriere-Liste in Zukunft vielleicht noch anpassen, aber für den Moment habe ich alle Dateien versioniert, die ich brauche.

Zu Remote-Repository pushen

Wie bereits in den Vorteilen erwähnt, könnt ihr diesen Ansatz auch verwenden, um ein „Backup“ eurer Konfigurations-Dateien zu erstellen. Auch wenn Git (oder jedes andere Versionsverwaltungstool) keine Alternative zu einem Backup ist, kann es doch vorteilhaft sein, das Repository auf einem externen Server zu haben. Da diese Konfiguration nicht unbedingt öffentlich sein sollte, verwende ich für meine ein privates Repository auf GitLab.com als Remote.

Das hat weiterhin den Vorteil, dass ich mir das Repository auf meinen Laptop klonen kann, um dann die Dateien einfacher in PhpStorm bearbeiten kann, als mit vim direkt auf dem Server. Ich kann auch sehr viel einfacher die Änderungen vergleichen und Commits rückgängig machen.

Änderungen automatisch versionieren

Ich mache die Commits (und Pushes) normalerweise manuell. Aber falls ihr häufig Änderungen an Dateien durch andere Prozesse habt, und jede Änderungen versionieren möchtet, dann könnt ihr einen Cron erstellen, der alle Änderungen commited. Dies ist ein Beispiel für einen Cron, der automatisch alle 30 Minuten alle Änderungen an der nginx Konfiguration commited:

30 * * * * cd /etc/nginx &amp;&amp; git add -A &amp;&amp; git commit -m "auto commit on `date`" &amp;&amp; git push

Selbst neue und gelöschte Dateien werden versioniert. Einen solchen Cron zu haben, kann aber auch potenziell zu Problemen führen, wenn eure Ignorieren-Liste nicht richtig aufgesetzt ist, da vielleicht eine neue Datei eine Logdatei ist, die sich häufig ändert. Wenn ihr also einen solchen Cron einsetzt, solltet ihr die automatischen Commits regelmäßig prüfen.

Fazit

Ich liebe Git! Man kann es für so viele verschiedene Dinge verwenden. Das Versionieren meiner Konfigurations-Dateien hat mir schon viel Zeit gespart, wenn ich versucht habe herauszufinden, wieso Dinge auf einmal kaputt waren. Aber auch, wenn ich Änderungen an mehreren Dateien auf einmal machen wollte (bei der lokalen Bearbeitung in PhpStorm).

Verwendet ihr einen ähnlichen Ansatz und möchtet diesen gerne hier teilen? Oder verwendet ihr Git noch für ganz andere Dinge? Dann schreibt es gerne in einen Kommentar.