restore_current_blog () vs switch_to_blog ()


23

Po każdym wystąpieniu switch_to_blog()należy zadzwonić, restore_current_blog()aby przywrócić bieżący (faktycznie poprzedni) blog.

Ale jeśli przeglądasz dwa lub więcej blogów i wywołujesz switch_to_blog()każdy z nich, czy istnieje jakiś powód, aby nie używać dodatkowego switch_to_blog()na końcu pętli, aby przełączyć się na oryginalny blog, zamiast dzwonić restore_current_blog()przy każdym przejściu.

Na przykład

Dlaczego nie:

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

zamiast:

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

Teraz to rozumiem, dziękuję za poprawienie mojej odpowiedzi;) Poprawiam wszystko.
Brasofilo,

Odpowiedzi:


19

Po każdej instancji switch_to_blog()ciebie trzeba nazwać restore_current_blog()inaczej WP będzie sądzić, że jest w trybie A „włączane” i potencjalnie mogą powrócić nieprawidłowe dane.

Jeśli zobaczysz kod źródłowy dla obu funkcji, zobaczysz, że te funkcje push / pop data w globalnej nazwie $GLOBALS['_wp_switched_stack']. Jeśli nie zadzwonisz restore_current_blog()po każdym switch_to_blog(), $GLOBALS['_wp_switched_stack']będzie pusty. Jeśli $GLOBALS['_wp_switched_stack']niepuste WP uważa, że ​​jest w trybie przełączonym, nawet jeśli wróciłeś do oryginalnego bloga przy użyciu switch_to_blog(). Funkcja trybu przełączanego działa ms_is_switched()i ma wpływ wp_upload_dir(). Jeśli wp_upload_dir()myśli, że jest w trybie komutacji, może zwrócić niepoprawne dane. wp_upload_dir()buduje adresy URL witryny, więc jest to bardzo ważna funkcja.

To jest prawidłowe użycie:

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

Dzięki, nie miałem okazji pracować nad zupą stałych i logiki, która wp_upload_dir()wykorzystuje się do generowania adresów URL, ale uwierzę ci, że to naprawdę powoduje błędy w działaniu. W każdym razie istnienie środków ms_is_switched()oznacza, że ​​moje alternatywne podejście powoduje, że funkcja nie zachowuje się zgodnie z oczekiwaniami i może uszkodzić wtyczki oraz rdzeń. Dzięki
Stephen Harris,

1
Jeśli jest to prawda, strona Codex dla restore_current_blog()wymaga aktualizacji, ponieważ mówi, że w przypadku wielu przełączników wystarczy zapisać bieżący, $blog_ida następnie użyć wielu switch_to_blog()połączeń.
Pat J

16

Jeśli chcesz uruchomić wiele blogów, nie musisz za każdym razem przywracać poprzedniego bloga. Jedyne, co rośnie, to $GLOBALS['_wp_switched_stack']tablica z identyfikatorami blogów, nie ma się czym martwić.

Pamiętaj jednak, restore_current_blog() że nie będzie już działać (!!!) Po drugim przełączeniu, ponieważ korzysta z poprzedniego bloga - który wtedy nie jest pierwszym blogiem. Zapisz więc pierwszy identyfikator bloga i zadzwoń…

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

… Zamiast restore_current_blog()kiedy skończysz. Zmienne globalne muszą zostać zresetowane, w przeciwnym razie napotkasz problemy wymienione przez @ user42826.

Wpływ na wydajność jest ogromny. Przeprowadziłem kilka testów na lokalnej instalacji z 12 witrynami:

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

Wynik:

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

Używanie restore_current_blog()po każdym przełączniku podwaja czas potrzebny tylko na przełączenie.


Myślałem, że nie ma żadnego powodu, aby tego nie robić. Był zdezorientowany, dlaczego restore_current_blog()po prostu nie pobrał poprzedniego identyfikatora bloga i wywołania switch_to_blog()- krótkie spojrzenie na źródło kodu i wygląda na to, że jest trochę duplikacji kodu ...
Stephen Harris

3
Nie sądzę, aby modyfikowanie globali bezpośrednio było dobrym pomysłem, ponieważ łączysz swój kod z wewnętrznymi elementami Core, co nie jest przyszłościowe. Lepiej jest prawidłowo używać interfejsu API.
Ian Dunn

2
@IanDunn Dla przypomnienia: i tak switch_to_blog()jest bardzo ograniczonym (zepsutym) interfejsem API. Jeśli kiedykolwiek WordPress poprawek , które mamy byłaby nasz kod tak. A WordPress nigdy nie porzuci swoich ukochanych globali.
fuxia

2
@IanDunn I don't think modifying the globals directly is a good idea, nie mów tego twórcom wp core;)
Ejaz

1
@JD Oczywiście musisz być świadomy kontekstu. W przypadku stanu już przełączonego może być konieczne utrzymanie poprawnego indeksu stosu. Prawdopodobnie szukałbym sposobu, aby tego uniknąć. Z drugiej strony jest to WordPress, więc może nie być innego wyjścia…
fuxia

1

Dzięki odpowiedzi @toscho. To żądanie w kolejce WP - zobacz aktualizacje tutaj . Do czasu, gdy zostanie to naprawione w WP, jeśli ktoś desperacko chce użyć standardu restore_current_blog(), oto inna metoda (popraw, jeśli się mylę):

wykonaj swoją funkcję, tj

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

}

i wykonaj tylko raz po zakończeniu wielu przełączników. (więcej: wp-obejmuje / ms-blogs.php )

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.