switch_to_blog ist eine praktische Funktion, um Websites („Blogs“) in einer Multisite zu wechseln. Du solltest aber vorsichtig damit sein, da Probleme mit Daten in gewissen Kontexten auftreten können.

Was tut die Funktion eigentlich?

An sich wechselt sie die Website-ID in $wpdb, dem Datenbank-Objekt in WordPress, und wechselt den Cache entsprechend. Das war’s praktisch auch schon. Auf diesem Wege erlaubt es Datenbank-/Cache-Änderung für jede gegebene Website.

Warum ist das ein Problem?

Es gibt viele weitere Funktionen, die von den Daten der aktuellen Website abhängig sind – und bei „aktuell“ meine ich die Website, bevor der Wechsel stattfand. Als Beispiel ist get_template_directory_uri abhängig von der Konstante WP_CONTENT_URL. Diese gibt die URL des wp-content-Ordners zurück. Für eine Website unter https://www.example.com gibt es somit https://www.example.com/wp-content zurück.

Wenn du jetzt die Website wechselst, beispielsweise https://www.example.com/new-site/, gibt WP_CONTENT_URL immer noch https://www.example.com/wp-content zurück, da sie vorher definiert wurde. Da es außerdem eine Konstante ist, kannst du sie nicht überschreiben.

Auch globale Daten wie das globale $post-Objekt werden von switch_to_blog nicht angefasst. Du musst sie demnach selbst anpassen, wenn du sie benötigst.

Wie kann ich die Probleme lösen?

Je nachdem, welche Daten zu verwendest, gibt es unterschiedliche Möglichkeiten, sie zu korrigieren. Manchmal kann es aber auch keine Lösung dafür geben.

get_template_directory_uri

Für das genannte Problem mit get_template_directory_uri kannst du den Filter theme_root_uri verwenden, um die URL zu überschreiben und die Website-URL der Website vor der Verwendung von switch_to_blog mit der Website-URL danach zu ersetzen.

Der Code sieht dann folgendermaßen aus:

$main_site_url = \site_url();

\switch_to_blog( $site_id );
\add_filter( 'theme_root_uri', static function( string $theme_root_uri, string $site_url ) use ( $main_site_url ): string {
	return \str_replace( $main_site_url, $site_url, $theme_root_uri );
}, 10, 2 );
\restore_current_blog();
Code-Sprache: PHP (php)

Er verwendet die generierte theme_root_uri und ersetzt die Website-URL der Haupt-Website (was die Website ist bevor du switch_to_blog ausgeführt hast) mit der Website-URL der aktuellen Website, nachdem du zu ihr gewechselt bist.

Verwendung von Beitrags-Metadaten

Ein anderes Problem kann auftreten, wenn du zu einer Website wechselst, um Beiträge abzurufen. Wenn du das machst und auch Metadaten von diesen Beiträgen via get_post_meta benötigst, stelle sicher, dass du dafür entweder die Website erneut wechselst oder die Daten bereits abrufst, bevor du die alte Website wiederherstellst, da sonst die Daten auf der wiederhergestellten Website nicht mehr abgerufen werden können.

Zurücksetzen der Website ist wichtig

Immer, wenn du die Website wechselst, merkt sich WordPress die Website, auf der du davor warst. Um zur vorherigen Website wieder zu wechseln, stelle sicher, restore_current_blog auszuführen, wenn du mit deinen Anpassungen an der anderen Website fertig bist.

Wenn du das nicht tust oder nicht so oft, wie du switch_to_blog verwendet hast, wirst du merkwürdig aussehende Probleme bekommen, da du am Ende die Daten von der falschen Website erhältst.

Beispiel

$site_ids = [ 2, 3, 4 ];

echo 'Current site: ' . \get_current_blog_id() . \PHP_EOL;

foreach ( $site_ids as $site_id ) {
	\switch_to_blog( $site_id );
	
	echo 'Switched to ' . $site_id . \PHP_EOL;
	echo \get_current_blog_id() . \PHP_EOL;
}

\restore_current_blog();

echo 'Restored site to: ' . \get_current_blog_id() . \PHP_EOL;
Code-Sprache: PHP (php)

Hier wechseln wir die Website dreimal, erst zur Website mit der ID 2, dann mit 3 und dann mit 4. Wir verwenden immer get_current_blog_id, um das zu verifizieren.

Wenn du nicht so erfahren damit bist, wie switch_to_blog funktioniert, magst du zu dem Schluss kommen, dass restore_current_blog am Ende die Website ID wieder auf 1 setzt, wie sie zu Anfang war. Die Ausgabe ist aber die folgende:

Current site: 1
Switched to 2
2
Switched to 3
3
Switched to 4
4
Restored site to: 3

Wie du siehst, wechselt restore_current_blog immer nur zu der Website, die davor verwendet wurde, bevor switch_to_blog das letzte Mal ausgeführt wurde. Um die Funktion oben zu korrigieren, muss restore_current_blog jedes Mal innerhalb der foreach-Schleife ausgeführt werden:

$site_ids = [ 2, 3, 4 ];

echo 'Current site: ' . \get_current_blog_id() . \PHP_EOL;

foreach ( $site_ids as $site_id ) {
	\switch_to_blog( $site_id );
	
	echo 'Switched to ' . $site_id . \PHP_EOL;
	echo \get_current_blog_id() . \PHP_EOL;
	\restore_current_blog();
}

echo 'Restored site to: ' . \get_current_blog_id() . \PHP_EOL;
Code-Sprache: PHP (php)

Das führt dann zu folgender Ausgabe:

Current site: 1
Switched to 2
2
Switched to 3
3
Switched to 4
4
Restored site to: 1

Fazit

Der hauptsächliche Verwendungsgrund von switch_to_blog ist das Ändern/Abrufen von Datenbank-/Cache-Informationen einer bestimmten Website, während man sich eigentlich im Kontext einer anderen Website befindet. Insbesondere bei Dateisystem-Funktionen oder Daten im globalen Kontext (wie das globale $post-Objekt) kann es immer sein, dass man sich noch im Kontext der ursprünglich aufgerufenen Website befindet.

Neuveröffentlichungen

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Um auf deiner eigenen Website zu antworten, gib die URL deiner Antwort ein, die einen Link zur Permalink-URL dieses Beitrags enthalten sollte. Deine Antwort wird dann (möglicherweise nach der Moderation) auf dieser Seite erscheinen. Möchtest du deine Antwort aktualisieren oder entfernen? Aktualisiere oder lösche deinen Beitrag und gib die URL deines Beitrags noch einmal ein. (Mehr über die Funktion von Webmentions erfahren)