restore_current_blog () vs switch_to_blog ()

23

Depois de cada instância, switch_to_blog()você deve ligar restore_current_blog()para restaurar o blog atual (na verdade, anterior).

Mas se você estiver percorrendo dois ou mais blogs e ligando switch_to_blog()para cada um deles, existe algum motivo para não usar um adicional switch_to_blog()no final do loop para alternar para o blog original em vez de ligar restore_current_blog()a cada passagem.

Por exemplo

Por que não:

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

ao invés de:

 foreach( $blog_ids as $blog_id ){
    switch_to_blog( $blog_id );
    //Do stuff
    restore_current_blog_id();
 }
Stephen Harris
fonte
Agora eu entendo isso, obrigado por corrigir essa minha resposta;) Estou revisando tudo.
23133 brasofilo

Respostas:

19

Depois de cada instância que switch_to_blog()você precisar chamar, o restore_current_blog()WP pensará que está no modo "alternado" e pode potencialmente retornar dados incorretos.

Se você visualizar o código fonte das duas funções, verá essas funções enviar / inserir dados em uma chamada global $GLOBALS['_wp_switched_stack']. Se você não ligar restore_current_blog()depois de cada switch_to_blog(), $GLOBALS['_wp_switched_stack']não estará vazio. Se $GLOBALS['_wp_switched_stack']não estiver vazio, o WP acha que está no modo alternado, mesmo que você tenha retornado ao blog original usando switch_to_blog(). A função de modo comutado é ms_is_switched()e afeta wp_upload_dir(). Se wp_upload_dir()pensa que está no modo comutado, pode retornar dados incorretos. wp_upload_dir()cria URLs para o site, por isso é uma função muito crítica.

Este é o uso correto:

 foreach( $blog_ids as $blog_id ){
    switch_to_blog( $blog_id );
    //Do stuff
    restore_current_blog();
 }
user42826
fonte
Obrigado, não tive chance de trabalhar com a sopa de constantes e lógica wp_upload_dir()empregada para gerar URLs, mas devo dizer que isso realmente resulta em comportamento de buggy. De qualquer forma, a existência de ms_is_switched()significa que minha abordagem alternativa faz com que a função não se comporte conforme o esperado e pode interromper os plug-ins e também o núcleo. Obrigado
Stephen Harris
1
Se isso for verdade, a página do Codex restore_current_blog()precisa de uma atualização, pois diz que, para vários comutadores, é necessário salvar apenas o atual $blog_ide usar várias switch_to_blog()chamadas.
Pat J
16

Se você deseja executar vários blogs, não há necessidade de restaurar o blog anterior a cada vez. A única coisa que cresce é $GLOBALS['_wp_switched_stack']- uma matriz com IDs de blog, nada para se preocupar.

Mas lembre- restore_current_blog() se de que não funcionará mais (!!!) Após a segunda opção, porque ele usa o blog anterior - que não é o primeiro blog da época. Portanto, armazene o primeiro ID do blog e ligue para…

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

... em vez de restore_current_blog()quando terminar. As variáveis ​​globais devem ser redefinidas ou você encontrará os problemas mencionados por @ user42826.

O impacto no desempenho é enorme. Eu executei alguns testes em uma instalação local com 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>';

Resultado:

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

O uso restore_current_blog()após cada opção duplica o tempo necessário apenas para a troca.

fuxia
fonte
Pensei que não havia motivo para não fazê-lo. Estava confuso porque restore_current_blog()não apenas retrive o ID do blog anterior e chamada switch_to_blog()- um olhar breve na fonte de código e parece que há um pouco de duplicação de código ...
Stephen Harris
3
Não acho que modificar diretamente os globais seja uma boa idéia, porque você está acoplando seu código aos internos do Core, o que não é à prova de futuro. É melhor usar a API corretamente.
Ian Dunn
2
@ IanDunn Apenas para constar: switch_to_blog()é uma API muito limitada (quebrada) de qualquer maneira. Se o WordPress resolver isso , precisamos refatorar nosso código de qualquer maneira. E o WordPress nunca desistirá de seus amados globais.
fuxia
2
@IanDunn I don't think modifying the globals directly is a good idea, não diga isso para desenvolvedores do núcleo wp;)
Ejaz
1
@JD Claro, você precisa estar ciente do contexto. No caso de um estado já alternado, talvez seja necessário manter o índice correto da pilha. Eu provavelmente procuraria uma maneira de evitar isso. Por outro lado, este é o WordPress, então pode não haver outro caminho ...
fuxia
1

Graças à resposta @toscho. Esta solicitação na fila do WP - veja as atualizações aqui . Até que seja consertado no WP, se alguém quiser desesperadamente usar o padrão restore_current_blog(), aqui está outro método (corrija se estiver errado):

faça sua função, ou seja

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

}

e execute apenas uma vez quando terminar seus vários comutadores. (mais: wp-includes / ms-blogs.php )

T.Todua
fonte