Resto_current_blog () vs switch_to_blog ()


23

Після кожного примірника switch_to_blog()вам слід зателефонувати, restore_current_blog()щоб відновити поточний (власне, попередній) блог.

Але якщо ви перебираєте два або більше блогів і дзвоните switch_to_blog()в кожен, чи є якась причина не використовувати додаткову switch_to_blog()в кінці циклу для переходу на оригінальний блог, а не дзвонити restore_current_blog()при кожному проході.

Напр

Чому ні:

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

замість:

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

Тепер я це розумію, дякую, що виправте цю відповідь;) Я все переглядаю.
brasofilo

Відповіді:


19

Після кожного примірника switch_to_blog()вам потрібно зателефонувати в restore_current_blog()іншому випадку, WP подумає, що він знаходиться в режимі "переключення" і потенційно може повернути невірні дані.

Якщо ви переглядаєте вихідний код для обох функцій, ви побачите ці функції push / pop даних у глобальній назві $GLOBALS['_wp_switched_stack']. Якщо ви не телефонуєте restore_current_blog()після кожного switch_to_blog(), $GLOBALS['_wp_switched_stack']буде не порожнім. Якщо $GLOBALS['_wp_switched_stack']не порожній WP вважає, що він перебуває в переключеному режимі, навіть якщо ви повернулися до початкового блогу за допомогою switch_to_blog(). Функція переключеного режиму єms_is_switched() і це впливає wp_upload_dir(). Якщо wp_upload_dir()він вважає, що він перебуває в комутованому режимі, він може повернути неправильні дані. wp_upload_dir()будує URL-адреси для сайту, тому це дуже критична функція.

Це правильне використання:

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

Дякую, я не мав шансу пропрацювати суп констант і логіки, що wp_upload_dir()використовує для генерування URL-адрес, але я вірю на те, що це справді призводить до помилкової поведінки. У будь-якому випадку, існування ms_is_switched()засобів мого альтернативного підходу призводить до того, що функція не веде себе так, як очікувалося, і може зламати плагіни, а також основні. Спасибі
Стівен Харріс

1
Якщо це правда, то для сторінки Codex restore_current_blog()потрібне оновлення, оскільки в ній сказано, що для декількох комутаторів потрібно лише зберегти поточний $blog_idта використовувати декілька switch_to_blog()викликів.
Пат J

16

Якщо ви хочете працювати з декількома блогами, не потрібно щоразу відновлювати попередній блог. Єдине, що росте - це$GLOBALS['_wp_switched_stack'] - це масив з ідентифікаторами блогу, про що не варто хвилюватися.

Але майте на увазі, після другого перемикання більше restore_current_blog() не працюватиме (!!) , Оскільки він використовує попередній блог - який тоді не перший блог. Тож зберігайте перший ідентифікатор блогу та телефонуйте…

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

… замість restore_current_blog() коли ви закінчите. Глобальні змінні повинні бути скинуті, інакше ви зіткнетеся з проблемами, згаданими @ user42826.

Вплив на продуктивність величезний. Я провів кілька тестів на локальній установці з 12 сайтів:

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

Результат:

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

Використання restore_current_blog()після кожного перемикача подвоює час, необхідний саме для перемикання.


Думав, що немає ніяких причин цього не робити. Був розгублений, чому restore_current_blog()просто не отримав попередній ідентифікатор блогу та зателефонував switch_to_blog()- короткий огляд джерела коду, і, здається, є трохи дублювання коду ...
Стівен Харріс

3
Я не думаю, що зміна глобалів безпосередньо не є хорошою ідеєю, тому що ви зв’язуєте свій код із внутрішніми процесорами Core, що не є надійним для майбутнього. Краще правильно використовувати API.
Іван Данн

2
@IanDunn Тільки для запису: switch_to_blog()це все-таки дуже обмежений (зламаний) API. Якщо WordPress коли - або виправлення , які ми повинні реорганізувати наш код в будь-якому випадку. І WordPress ніколи не відмовиться від улюблених глобалів.
fuxia

2
@IanDunn I don't think modifying the globals directly is a good idea, не кажи, що це wp core developer;)
Ejaz

1
@JD Звичайно, потрібно бути в курсі контексту. У випадку вже переключеного стану, можливо, вам доведеться навіть підтримувати правильний індекс стека. Я, певно, шукав би способу цього уникнути. З іншого боку, це WordPress, тому іншого шляху не може бути…
fuxia

1

Завдяки відповіді @toscho Цей запит у черзі WP - дивіться оновлення тут . До фіксованого WP, якщо хтось відчайдушно хоче використовувати стандартrestore_current_blog() , то ось ще один метод (будь ласка, виправте, якщо я помиляюся):

зробити свою функцію, тобто

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

}

і виконати лише один раз, коли закінчите кілька комутаторів. (докладніше: wp-include / ms-blogs.php )

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.