Wenn Ihre WordPress-Website auf eine neue Domain umgezogen wird oder Sie eine Staging-Kopie in den Live-Betrieb übernehmen, taucht die alte Adresse nicht nur auf der Seite „Einstellungen“ auf: Sie ist auch im Text der Beiträge, in den Bildtiteln, in den Widgets sowie in den Einstellungen der WordPress-Themes und Plugins enthalten. Der WP-CLI-Befehl „wp search-replace“ ersetzt all dies in einem Schritt und – was am wichtigsten ist – beeinträchtigt dabei auch nicht die serialisierten Daten.
Wenn die Website über das WP Toolkit verwaltet wird, kann die Adressänderung in einfacheren Fällen auch über den Menüpunkt „Aktualisierte Website-URL“ im ⋮-Menü der Website-Zeile vorgenommen werden. Dieser Artikel beschreibt den Befehlszeilenweg, der alle Schritte aufzeigt und eine lückenlose Überprüfung ermöglicht. Bei cPanel-Hosting-Paketen ist WP-CLI in den Paketen mit SSH-Zugang verfügbar; die Grundlagen werden im Artikel zur Verwendung von WP-CLI beschrieben.
Warum ist ein einfacher SQL-Austausch nicht sinnvoll?
WordPress und die Plugins speichern viele Einstellungen im serialisierten PHP-Format, das vor jedem Text dessen Länge in Byte angibt: „s:22:"https://regi-domain.hu"“. Wenn ein SQL-REPLACE()-Befehl oder ein Texteditor die Domain in der SQL-Datei ersetzt, ändert sich der Text, nicht jedoch die Länge. PHP kann den Wert in diesem Fall nicht wieder auslesen, WordPress verwendet den Standardwert, und die Widgets oder Plugin-Einstellungen bleiben ohne Fehlermeldung leer.
Ein heikler Aspekt: Wenn die alte und die neue Domain zufällig gleich lang sind, scheint der einfache Austausch zunächst zu funktionieren, und der Fehler tritt erst beim nächsten Umzug auf. Bei Texten mit Akzenten wird die Länge in Bytes gezählt; ein Buchstabe mit Akzent entspricht 2 Bytes, sodass es sich nicht lohnt, dies manuell zu korrigieren.
Das Plugin „wp search-replace“ entpackt den serialisierten Wert, ersetzt die Werte innerhalb der Struktur, schreibt sie anschließend wieder zurück und berechnet die Längen neu.
1. Speichern
Sichern Sie die Datenbank, bevor Sie Änderungen vornehmen. Auf den cPanel-Servern von aWh kann „wp db export“ nicht verwendet werden (die PHP-Funktion „proc_open“ ist deaktiviert); verwenden Sie daher direkt den Befehl „mysqldump“. Die Erstellung der Datei „~/.my.cnf“, die das Datenbankpasswort enthält, wird im Artikel zur Verwendung von WP-CLI erläutert.
cd ~/public_html
mysqldump --single-transaction --no-tablespaces "$(wp config get DB_NAME)" > ~/domainvaltas-elott.sql
tail -1 ~/domainvaltas-elott.sql
Die letzte Zeile sollte lauten: „-- Dump completed on …“. Sollte ein Fehler auftreten, führen Sie folgende Wiederherstellung durch:
mysql "$(wp config get DB_NAME)" < ~/domainvaltas-elott.sql
Die Funktion „Backup/Wiederherstellung“ des WP Toolkits sowie die tägliche JetBackup-Sicherung sind ebenfalls ausreichend (Sicherungsoptionen), doch lässt sich das System anhand einer aktuellen SQL-Datei innerhalb weniger Minuten wiederherstellen.
2. Berechnen Sie, was Sie austauschen werden
Suchen Sie nach der reinen Domain ohne Protokoll. Der Block-Editor und viele Plugins speichern die Adresse im JSON-Format als „https:\/\/regi-domain.hu“; die Suche nach „https://regi-domain.hu“ findet diese nicht, die Suche nach „regi-domain.hu“ hingegen schon.
wp db search 'regi-domain.hu' --all-tables --stats
Am Ende der Ausgabe wird die Anzahl der Treffer angezeigt, zum Beispiel „Success: Found 7 matches“.
3. Testlauf
wp search-replace 'regi-domain.hu' 'uj-domain.hu' --all-tables --skip-columns=guid --precise --report-changed-only --dry-run
Die Schaltflächen:
--dry-run: Es wird nichts geschrieben, sondern lediglich angezeigt, in welcher Spalte welcher Tabelle wie viele Änderungen vorgenommen würden.--all-tables: Durchsucht auch die eigenen Tabellen der Plugins (auf dem Bild ist beispielsweise eine WooCommerce-Tabelle zu sehen). Wenn die Datenbank Tabellen mehrerer Websites enthält, verwenden Sie stattdessen den Schalter--all-tables-with-prefix, damit nur Tabellen mit dem eigenen Präfix berücksichtigt werden.--skip-columns=guid: Das Feld „guid“ der Einträge ist eine eindeutige Kennung und keine Adresse; wenn Sie es überschreiben, werden alle alten Einträge von den Newsreadern als neu angezeigt.--precise: Jede Zeile wird mit PHP verarbeitet; dies ist zwar langsamer, bietet jedoch bei komplexen Daten von Seitenerstellern mehr Sicherheit.--report-changed-only: Es werden nur die Tabellen ausgegeben, in denen tatsächlich eine Änderung stattfindet.
Vergleichen Sie das Ergebnis mit der Zahl aus Schritt 2. Wenn die Anzahl der Treffer deutlich höher ist, ist der gesuchte Text auch Teil eines anderen Namens (beispielsweise kommt „pelda.hu“ auch in der Adresse „masikpelda.hu“ vor); in diesem Fall sollten Sie die längere, genauere Form verwenden. Wenn die Anzahl deutlich geringer ist, befinden Sie sich wahrscheinlich im falschen Website-Ordner.
4. Der Austausch
Führen Sie denselben Befehl ohne den Parameter „--dry-run“ aus, damit genau das ausgeführt wird, was Sie überprüft haben:
wp search-replace 'regi-domain.hu' 'uj-domain.hu' --all-tables --skip-columns=guid --precise --report-changed-only
Die letzte Zeile lautet „Success: Made N replacements.“, wobei N der Anzahl der Testläufe entspricht. Bei einer Multisite-Installation fügen Sie bitte den Schalter „--network“ hinzu, da sich andernfalls nur die Adresse der HauptWebsite ändert.
5. Umstellung von HTTP auf HTTPS in einem separaten Schritt
Bitte führen Sie den Wechsel der Domain und des Protokolls nicht in einem einzigen Suchvorgang durch. Wechseln Sie zunächst die Domain und anschließend das Protokoll auf der neuen Domain:
wp search-replace 'http://uj-domain.hu' 'https://uj-domain.hu' --all-tables --skip-columns=guid --precise --report-changed-only
wp option update siteurl 'https://uj-domain.hu'
wp option update home 'https://uj-domain.hu'
Wenn Sie lediglich auf HTTPS umstellen, ohne die Domain zu wechseln, ist dieser Schritt bereits abgeschlossen. Der Artikel zum Thema „Mixed Content“ hilft Ihnen dabei, fehlende http://-Verweise aufzuspüren.
6. Caches leeren
Solange ein Cache noch alte Inhalte bereitstellt, ist das Ergebnis der Aktualisierung nicht sichtbar:
wp cache flush
wp transient delete --all
wp rewrite flush
Leeren Sie anschließend den eigenen Speicher des Plugins (z. B. AccelerateWP, LiteSpeed Cache, WP Rocket) über die Benutzeroberfläche des Plugins und, falls Sie ein CDN nutzen, auch dort.
7. Was nicht in der Datenbank enthalten ist
Die Funktion „search-replace“ überschreibt lediglich die Datenbank. Bitte überprüfen Sie auch die folgenden Dateien:
grep -n "WP_HOME\|WP_SITEURL\|DOMAIN_CURRENT_SITE" ~/public_html/wp-config.php
grep -rn "regi-domain\.hu" ~/public_html/.htaccess ~/public_html/wp-content/themes/
Sollten in der Datei „wp-config.php“ die Einträge „WP_HOME“ oder „WP_SITEURL“ mit der alten Adresse enthalten sein, werden diese in der Datenbank überschrieben: Die Änderung erfolgt fehlerfrei, dennoch wird die alte Adresse angezeigt, und auf der Seite „Einstellungen“ sind die Felder ausgegraut. Bitte korrigieren oder löschen Sie diese Zeilen. Überprüfen Sie außerdem die in die Vorlage eingebetteten Adressen, die Weiterleitungen in der Datei „.htaccess“, die Einstellungen für CDN, SMTP und Statistik-Plugins sowie die bei externen Diensten (Zahlungsgateway, API) registrierten Rückrufadressen.
Elementor speichert Ihre Inhalte in doppelt kodiertem JSON, und auch in den kompilierten CSS-Dateien sind absolute Adressen enthalten. Verwenden Sie auf der Seite „Tools“ (Werkzeuge) im Elementor-Menü die Funktion „Replace URL“ (URL ersetzen) und generieren Sie anschließend das CSS neu:
wp elementor flush-css
Auch andere Seitenbaukästen (Divi, Beaver Builder, WPBakery) verfügen über einen eigenen CSS-Cache; leeren Sie diesen, bevor Sie zu dem Schluss kommen, dass der Austausch fehlgeschlagen ist.
Überprüfung
wp option get siteurl && wp option get home
wp db search 'regi-domain.hu' --all-tables --stats
curl -sI https://uj-domain.hu/ | head -5
curl -s https://uj-domain.hu/ | grep -c 'regi-domain\.hu'
Die URLs „siteurl“ und „home“ müssen die neue Adresse anzeigen, die „wp db search“-Abfrage darf höchstens in der Spalte „guid“ eine Übereinstimmung finden, die Antwort von „curl -sI“ muss „200“ lauten und darf nicht auf die alte Domain zurückleiten, und der letzte Befehl muss „0“ ausgeben. Ist der Wert nicht null, ist die alte Adresse an einer der in Schritt 7 aufgeführten Stellen noch vorhanden.
Öffnen Sie anschließend im Admin-Bereich die Seiten, auf denen die serialisierten Einstellungen gespeichert sind: „Darstellung“ › „Widgets“, „Anpassung“, „WooCommerce-Versandzonen“ und die Vorlagen des Seitenbauers. Sollte eine dieser Seiten leer sein, obwohl dort zuvor Einstellungen vorhanden waren, stellen Sie die Sicherung wieder her und führen Sie den Austausch mit dem Schalter „--precise“ erneut durch.
Häufige Fehler
Es findet kein Austausch statt, obwohl die alte Domain überall vorhanden ist. Sie haben den Befehl im falschen Verzeichnis ausgeführt (siehe: wp option get siteurl), oder die Adresse ist anders gespeichert, als Sie gesucht haben. Suchen Sie nach einer kürzeren Form: wp db search 'regi-domain' --all-tables --stats.
Die Umstellung war erfolgreich, doch die Seite leitet weiterhin auf die alte Adresse weiter. Die häufigsten Ursachen in der Reihenfolge ihrer Häufigkeit sind: „WP_HOME“/„WP_SITEURL“ in der Datei „wp-config.php“, ein nicht geleerter Cache, ein CDN, das die alte Adresse bereitstellt, oder eine Weiterleitung in der Datei „.htaccess“.
Die Unterseiten des Multi-Site-Netzwerks befinden sich weiterhin unter der alten Adresse. Entweder wurde der Schalter „--network“ nicht gesetzt, oder die Konstante „DOMAIN_CURRENT_SITE“ in der Datei „wp-config.php“ enthält noch die alte Domain. Bitte korrigieren Sie dies, führen Sie den Befehl erneut mit dem Schalter „--network“ aus und überprüfen Sie dies mit dem Befehl: „wp site list --field=url“.
Live-Online-Shop. Bei einem Online-Shop sollten Sie die Bestellungen für die Dauer des Wechsels aussetzen (beispielsweise durch den Wartungsmodus), das Ergebnis überprüfen und den Shop erst danach wieder öffnen. Falls der Domainwechsel mit einem Serverumzug einhergeht, wird der gesamte Vorgang im Artikel zur WordPress-Migration beschrieben.

