# get_current_blog_id et switch_to_blog : la paire qu’on doit refermer par restore

> Une boucle sur un réseau multisite oublie un restore_current_blog, et c'est tout le reste du script qui continue d'agir sur le mauvais site sans le signaler.

- Auteur : Clément Hadrot
- Publié le : 2025-10-04
- Mis à jour le : 2025-10-04
- Catégorie : Astuces
- URL : https://wpmoderne.dev.wordpress-developpement.fr/tips/get-current-blog-id-switch-to-blog-refermer-restore/

## L’essentiel

- switch_to_blog change tout le contexte global
- restore_current_blog doit toujours suivre, même en cas d'erreur
- get_current_blog_id vérifie le contexte avant d'agir

Un appel à `switch_to_blog()` sans son `restore_current_blog()` correspondant, plus loin dans le script, et c'est tout le code exécuté après ce point qui continue de croire être sur le site initial — options, requêtes, chemins de fichiers compris. Sur un réseau multisite, cette discipline n'est pas optionnelle : elle conditionne la fiabilité de tout script qui doit lire ou écrire sur plusieurs sites du même réseau.

Trois fonctions natives forment un ensemble cohérent pour ce besoin : `get_current_blog_id()` pour connaître le site courant, `switch_to_blog()` pour en changer temporairement, et `restore_current_blog()` pour revenir en arrière proprement.

## Ce que change réellement switch_to_blog

`switch_to_blog( int $new_blog_id )` ne se contente pas de changer une variable : elle recharge les tables associées au site cible (options, métadonnées, taxonomies) dans le contexte global de WordPress. Toute fonction appelée après ce point — `get_option()`, `WP_Query`, `get_posts()` — agit alors comme si elle s'exécutait directement sur le site cible, pas sur celui d'origine.

C'est justement cette portée globale qui rend l'oubli du `restore_current_blog()` dangereux : contrairement à une variable locale qui disparaîtrait naturellement en sortant d'une fonction, ce changement de contexte persiste pour tout le reste de la requête en cours, y compris dans du code totalement indépendant appelé plus tard.

## Checklist avant d'écrire une boucle switch_to_blog

> L'essentiel à retenir : switch_to_blog change tout le contexte global ; restore_current_blog doit toujours suivre, même en cas d'erreur ; get_current_blog_id vérifie le contexte avant d'agir

1. Vérifier avec `get_current_blog_id()` quel est le site de départ, si cette information doit être réutilisée après la boucle.
2. Encadrer chaque `switch_to_blog()` d'un `restore_current_blog()` correspondant, dans la même fonction, jamais dans deux fonctions séparées.
3. Utiliser `try`/`finally` si le code entre les deux appels peut lever une exception, pour garantir que `restore_current_blog()` s'exécute même en cas d'erreur.
4. Ne jamais imbriquer un `switch_to_blog()` dans une fonction de rappel exécutée en dehors du contrôle direct du script, comme un hook déclenché ailleurs.
5. Vérifier en fin de script, avec `get_current_blog_id()`, que le site courant correspond bien à celui de départ.

## Un exemple : recopier un réglage sur tous les sites du réseau

Une extension réseau qui doit appliquer un même réglage à chaque site pourrait s'écrire ainsi, avec la discipline de fermeture systématique :

```
function reseau_appliquer_reglage_a_tous_les_sites( $valeur ) {
    $sites = get_sites( array( 'fields' => 'ids' ) );

    foreach ( $sites as $blog_id ) {
        switch_to_blog( $blog_id );

        update_option( 'reglage_partage_reseau', $valeur );

        restore_current_blog();
    }
}
```

Remarquez que `restore_current_blog()` se trouve à l'intérieur de la boucle, juste après le traitement, et non regroupé une seule fois à la fin : chaque `switch_to_blog()` doit être refermé avant le suivant, pour ne jamais empiler des changements de contexte les uns sur les autres sans les dépiler correctement.

## Le piège d'un retour anticipé

Un `return` placé entre `switch_to_blog()` et `restore_current_blog()` — pour sortir d'une fonction en cas de condition particulière — laisse le contexte basculé sans jamais le restaurer. C'est l'erreur la plus fréquente rencontrée en revue de code sur ce sujet : une condition d'arrêt anticipé ajoutée après coup, sans repenser l'ensemble de la structure.

- Préférer une structure qui place toute condition de sortie avant le `switch_to_blog()`, jamais après.
- À défaut, restaurer explicitement le contexte juste avant chaque `return` intermédiaire.
- `WP_Site_Query` et les fonctions du cœur réseau restent utilisables sans `switch_to_blog()` pour de simples lectures de métadonnées de site, ce qui évite parfois le problème entièrement.

> Sur un script réseau qui parcourt plusieurs sites, mieux vaut structurer chaque itération autour d'un seul switch_to_blog et d'un seul restore_current_blog, sans branche de sortie intermédiaire entre les deux.

## En résumé

La paire `switch_to_blog()` / `restore_current_blog()` n'a de sens que si elle est toujours complète : chaque changement de contexte doit être refermé avant que le script ne continue son exécution normale. `get_current_blog_id()` sert de vérification à la fois avant et après, pour confirmer que le contexte est bien celui attendu. Cette discipline coûte peu à respecter et évite des bugs particulièrement difficiles à diagnostiquer, puisqu'ils se manifestent souvent loin du code fautif.
