restore_current_blog () vs switch_to_blog ()

22

Después de cada instancia de switch_to_blog() debe llamar a restore_current_blog() para restaurar el actual (en realidad, anterior) blog.

Pero si recorres dos o más blogs y llamas a switch_to_blog() en cada uno, ¿hay alguna razón no para usar un switch_to_blog() adicional al final del ciclo para cambiar a el blog original en lugar de llamar a restore_current_blog() en cada pase.

Por ejemplo,

¿Por qué no?

 $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 );

en lugar de:

 foreach( $blog_ids as $blog_id ){
    switch_to_blog( $blog_id );
    //Do stuff
    restore_current_blog_id();
 }
    
pregunta Stephen Harris 02.03.2013 - 21:37

3 respuestas

18

Después de cada instancia de switch_to_blog() , usted necesita para llamar a restore_current_blog() ; de lo contrario, WP pensará que está en modo "conmutado" y puede devolver datos incorrectos.

Si ve el código fuente de ambas funciones, verá esas funciones insertar / extraer datos en un global llamado $GLOBALS['_wp_switched_stack'] . Si no llama a restore_current_blog() después de cada switch_to_blog() , $GLOBALS['_wp_switched_stack'] no estará vacío. Si $GLOBALS['_wp_switched_stack'] no está vacío, WP cree que está en un modo conmutado, incluso si cambió al blog original usando switch_to_blog() . La función de modo conmutado es ms_is_switched() y afecta a wp_upload_dir() . Si wp_upload_dir() piensa que está en un modo conmutado, puede devolver datos que son incorrectos. wp_upload_dir() construye URL para el sitio, por lo que es una función muy importante.

Para tu información, me encontré con este problema usando un complemento que usaba switch_to_blog() . El complemento no usó restore_current_blog() para restaurar, en su lugar usó switch_to_blog() para volver al sitio original. Con el complemento activo, todas las URL de mi sitio que se generaron eran incorrectas.

Este es el uso correcto:

 foreach( $blog_ids as $blog_id ){
    switch_to_blog( $blog_id );
    //Do stuff
    restore_current_blog();
 }
    
respondido por el user42826 17.11.2013 - 05:27
16

Si desea ejecutar varios blogs, no es necesario restaurar el blog anterior cada vez. Lo único que crece es $GLOBALS['_wp_switched_stack'] : una matriz con ID de blog, nada de qué preocuparse.

Pero ten en cuenta que restore_current_blog() ya no funcionará después del segundo cambio, porque usa el blog anterior, que no es el blog primero . Así que guarde la primera identificación del blog y llame ...

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

... en lugar de restore_current_blog() cuando haya terminado. Las variables globales deben restablecerse, o se encontrará con los problemas mencionados por @ user42826.

El impacto en el rendimiento es enorme. He realizado algunas pruebas en una instalación local con 12 sitios:

$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>';

Resultado:

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

El uso de restore_current_blog() después de cada cambio duplica el tiempo que se necesita solo para cambiar.

    
respondido por el fuxia 02.03.2013 - 21:46
1

Gracias a la respuesta de @toscho. Esta solicitud en la cola de WP: vea las actualizaciones aquí . Hasta que esto se arregle en WP, si alguien desea usar desesperadamente el estándar restore_current_blog() , entonces aquí hay otro método (corríjalo si estoy equivocado):

haga su función, es decir,

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();
    }

}

y ejecute solo una vez cuando termine sus múltiples interruptores. (más: wp-includes / ms-blogs.php )

    
respondido por el T.Todua 08.09.2016 - 10:07

Lea otras preguntas en las etiquetas