web-dev-qa-db-fra.com

restore_current_blog () vs switch_to_blog ()

Après chaque instance de switch_to_blog() , vous devez appeler restore_current_blog() pour restaurer le blog actuel (en réalité, précédent).

Mais si vous parcourez deux blogs ou plus et appelez switch_to_blog() sur chacun, existe-t-il une raison not d'utiliser une switch_to_blog() supplémentaire à la fin de la boucle pour basculer vers le blog d'origine plutôt que d'appeler restore_current_blog() à chaque passe.

Par exemple.

Pourquoi pas:

 $original_blog_id = get_current_blog_id();
 foreach( $blog_ids as $blog_id ){
    switch_to_blog( $blog_id );
    //Do stuff
 }
 switch_to_blog( $original_blog_id );

au lieu de:

 foreach( $blog_ids as $blog_id ){
    switch_to_blog( $blog_id );
    //Do stuff
    restore_current_blog_id();
 }
22
Stephen Harris

Après chaque instance de switch_to_blog(), vous need appelez restore_current_blog(), sinon WP pensera qu'il est en mode "commuté" et peut potentiellement renvoyer des données incorrectes.

Si vous affichez le code source des deux fonctions, vous verrez ces fonctions Transférer des données dans un fichier global appelé $GLOBALS['_wp_switched_stack']. Si vous n'appelez pas restore_current_blog() après chaque switch_to_blog(), $GLOBALS['_wp_switched_stack'] sera non vide. Si $GLOBALS['_wp_switched_stack'] n'est pas vide, WP pense qu'il est en mode commuté, même si vous êtes revenu au blog d'origine à l'aide de switch_to_blog(). La fonction de mode commuté est ms_is_switched() et cela affecte wp_upload_dir() . Si wp_upload_dir() pense qu'il est en mode commuté, il peut renvoyer des données incorrectes. wp_upload_dir() construit des URL pour le site, donc c'est une fonction très critique.

Pour info, j'ai rencontré ce problème en utilisant un plugin qui utilisait switch_to_blog(). Le plug-in n'a pas utilisé restore_current_blog() pour restaurer, mais plutôt switch_to_blog() pour revenir au site d'origine. Avec le plugin actif, toutes les URL de mon site générées étaient incorrectes.

C'est l'utilisation correcte:

 foreach( $blog_ids as $blog_id ){
    switch_to_blog( $blog_id );
    //Do stuff
    restore_current_blog();
 }
19
user42826

Si vous souhaitez parcourir plusieurs blogs, il n'est pas nécessaire de restaurer le blog précédent à chaque fois. La seule chose qui se développe est $GLOBALS['_wp_switched_stack'] - un tableau avec des identifiants de blog, rien d’inquiétant.

Mais gardez à l'esprit que restore_current_blog() ne fonctionnera plus après le deuxième commutateur, car il utilise le blog précédent - qui n'est pas le premier blog alors. Enregistrez donc le premier identifiant de blog et appelez…

switch_to_blog( $first_blog_id ); 
unset ( $GLOBALS['_wp_switched_stack'] );
$GLOBALS['switched'] = false; 

… Au lieu de restore_current_blog() lorsque vous avez terminé. Les variables globales doivent être réinitialisées, sinon vous rencontrerez les problèmes mentionnés par @ user42826.

L'impact sur les performances est énorme. J'ai effectué des tests sur une installation locale avec 12 sites:

$sites = wp_get_sites();

print '<pre>' . count( $sites ) . " sites\n";

timer_start();

print 'With restore_current_blog():    ';

foreach ( $sites as $site ) {
    switch_to_blog( $site[ 'blog_id' ] );
    restore_current_blog();
}

timer_stop( 1, 9 );

print "\nWithout restore_current_blog(): ";

timer_start();

$current_site = get_current_blog_id();

foreach ( $sites as $site ) {
    switch_to_blog( $site[ 'blog_id' ] );
}

switch_to_blog( $current_site );
$GLOBALS['_wp_switched_stack'] = array();
$GLOBALS['switched']           = FALSE;

timer_stop( 1, 9 );

print '</pre>';

Résultat:

12 sites
With restore_current_blog():    0.010648012
Without restore_current_blog(): 0.005203962

Utiliser restore_current_blog() après chaque commutateur double le temps nécessaire à la commutation.

16
fuxia

Merci à @toscho répondre. Cette demande en file d'attente de WP - voir updates here . Jusqu'à ce que cela soit corrigé dans WP, si quelqu'un veut utiliser désespérément restore_current_blog(), voici une autre méthode (merci de corriger si je me trompe):

rendre votre fonction, c'est-à-dire.

function restore_original_blog_X(){

    if(!empty(($GLOBALS['_wp_switched_stack'][0])){
        $GLOBALS['blog_id']= $GLOBALS['_wp_switched_stack'][0];
        $GLOBALS['_wp_switched_stack'] = array($GLOBALS['_wp_switched_stack'][0]);
        restore_current_blog();
    }

}

et n'exécuter qu'une seule fois lorsque vous avez terminé vos multiples commutateurs. (plus: wp-includes/ms-blogs.php )

1
T.Todua