restore_current_blog () vs switch_to_blog ()


23

Dopo ogni istanza switch_to_blog(), dovresti chiamare restore_current_blog()per ripristinare il blog attuale (in realtà, precedente).

Ma se stai attraversando due o più blog e stai chiamando switch_to_blog()ciascuno, c'è qualche motivo per non usare un altro switch_to_blog()alla fine del ciclo per passare al blog originale piuttosto che chiamare restore_current_blog()ad ogni passaggio.

Per esempio

Perchè 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 );

invece di:

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

Ora capisco questo, grazie per aver corretto la mia risposta;) Sto rivedendo tutto.
brasofilo,

Risposte:


19

Dopo ogni istanza di switch_to_blog()te necessario chiamare restore_current_blog()altrimenti WP penserà di essere in una modalità "commutata" e potrebbe potenzialmente restituire dati errati.

Se visualizzi il codice sorgente per entrambe le funzioni, vedrai quelle funzioni push / pop data in un globale chiamato $GLOBALS['_wp_switched_stack']. Se non si chiama restore_current_blog()dopo ogni switch_to_blog(), $GLOBALS['_wp_switched_stack']sarà non vuoto. Se $GLOBALS['_wp_switched_stack']non è vuoto, WP pensa che sia in modalità commutata, anche se è tornato al blog originale usando switch_to_blog(). La funzione della modalità commutata è ms_is_switched()e influenza wp_upload_dir(). Se wp_upload_dir()pensa che sia in una modalità commutata, può restituire dati errati. wp_upload_dir()crea URL per il sito, quindi è una funzione molto critica.

Questo è l'uso corretto:

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

Grazie, non ho avuto la possibilità di elaborare la minestra di costanti e logiche che wp_upload_dir()impiega per generare URL, ma prenderò la tua parola che ciò si traduce in un comportamento errato. In ogni caso, l'esistenza di ms_is_switched()mezzi il mio approccio alternativo fa sì che la funzione non si comporti come previsto e potrebbe interrompere i plug-in e il core. Grazie
Stephen Harris,

1
Se questo è vero, allora la pagina Codex restore_current_blog()richiede un aggiornamento, poiché dice che per più switch, è sufficiente salvare la corrente $blog_ide quindi utilizzare più switch_to_blog()chiamate.
Pat J,

16

Se si desidera eseguire più blog, non è necessario ripristinare il blog precedente ogni volta. L'unica cosa che cresce è $GLOBALS['_wp_switched_stack']: un array con ID blog, niente di cui preoccuparsi.

Ma tieni presente restore_current_blog() che non funzionerà più (!!!) Dopo il secondo passaggio, perché utilizza il blog precedente, che non è il primo blog allora. Quindi memorizza il primo ID blog e chiama ...

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

… invece di restore_current_blog() quando hai finito. Le variabili globali devono essere ripristinate, altrimenti si verificheranno i problemi menzionati da @ user42826.

L'impatto sulle prestazioni è enorme. Ho eseguito alcuni test su un'installazione locale con 12 siti:

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

Risultato:

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

L'uso restore_current_blog()dopo ogni interruttore raddoppia il tempo necessario solo per il passaggio.


Pensavo non ci fosse motivo di non farlo. Era confuso perché restore_current_blog()non si limitasse a recuperare l'ID del blog precedente e chiamare switch_to_blog()- una breve occhiata alla fonte del codice e sembra che ci sia un po 'di duplicazione del codice ...
Stephen Harris

3
Non penso che modificare direttamente i globi sia una buona idea, perché stai accoppiando il tuo codice agli interni di Core, che non è a prova di futuro. È meglio usare l'API correttamente.
Ian Dunn,

2
@IanDunn Solo per la cronaca: switch_to_blog()è comunque un'API molto limitata (non funzionante). Se WordPress mai correzioni che , dobbiamo refactoring nostro codice in ogni caso. E WordPress non rinuncerà mai ai suoi amati globali.
fuxia

2
@IanDunn I don't think modifying the globals directly is a good idea, non dirlo agli sviluppatori core;)
Ejaz,

1
@JD Ovviamente, devi essere consapevole del contesto. Nel caso di uno stato già commutato, potrebbe essere necessario mantenere anche l'indice corretto dello stack. Probabilmente avrei cercato un modo per evitarlo. D'altra parte, questo è WordPress, quindi potrebbe non esserci altro modo ...
fuxia

1

Grazie alla risposta @toscho. Questa richiesta in coda a WP - vedi gli aggiornamenti qui . Fino a quando non viene risolto il problema con WP, se qualcuno desidera disperatamente utilizzare lo standard restore_current_blog(), ecco un altro metodo (correggi se sbaglio):

fai la tua funzione, ad es

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

}

ed eseguirlo una sola volta al termine dei vari switch. (altro: wp-Includes / ms-blogs.php )

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.