restore_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 จะคิดว่ามันอยู่ในโหมด "เปลี่ยน" และอาจส่งคืนข้อมูลที่ไม่ถูกต้อง

ถ้าคุณดูซอร์สโค้ดสำหรับฟังก์ชั่นทั้งคุณจะเห็นฟังก์ชันเหล่านั้นผลักดัน / $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()วิธีการทางเลือกของฉันส่งผลให้ฟังก์ชั่นไม่ทำงานตามที่คาดไว้และอาจทำให้ปลั๊กอินแตกเป็นหลัก ขอบคุณ
Stephen Harris

1
หากนี่เป็นเรื่องจริงหน้า Codex สำหรับrestore_current_blog()ความต้องการการอัพเดทเนื่องจากมันบอกว่าสำหรับสวิตช์หลายตัวหนึ่งต้องการเพียงแค่บันทึกปัจจุบัน$blog_idและใช้การswitch_to_blog()เรียกหลายครั้ง
Pat J

16

หากคุณต้องการเรียกใช้หลาย ๆ บล็อกไม่จำเป็นต้องกู้คืนบล็อกก่อนหน้าในแต่ละครั้ง สิ่งเดียวที่เพิ่มขึ้นคือ$GLOBALS['_wp_switched_stack']- อาร์เรย์ที่มี ID บล็อกไม่มีอะไรต้องกังวล

แต่โปรดจำไว้ว่าrestore_current_blog() จะไม่ทำงาน (!!!)อีกต่อไปหลังจากเปลี่ยนครั้งที่สองเพราะใช้บล็อกก่อนหน้า - ซึ่งไม่ใช่บล็อกแรกแล้ว ดังนั้นเก็บ ID บล็อกแรกและโทร ...

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()ไม่เพียง แต่ดึงข้อมูล ID บล็อกเดิมและการโทรswitch_to_blog()กลับมาดูสั้น ๆ ที่ซอร์สโค้ดและดูเหมือนว่าจะมีการทำซ้ำรหัสเล็กน้อย ...
Stephen Harris

3
ฉันไม่คิดว่าการปรับเปลี่ยน globals โดยตรงเป็นความคิดที่ดีเพราะคุณกำลังเชื่อมโยงรหัสของคุณเข้ากับ internals ของ Core ซึ่งไม่ได้เป็นหลักฐานในอนาคต ควรใช้ API อย่างถูกต้อง
Ian Dunn

2
@IanDunn เพียงเพื่อบันทึก: switch_to_blog()เป็น API ที่ จำกัด (ใช้งานไม่ได้) อย่างมาก หากเวิร์ดเพรสแก้ไขนั้นเราจะต้องปรับโครงสร้างรหัสของเราใหม่ และ WordPress จะไม่ยอมแพ้กลมกลืนอันเป็นที่รักของมัน
fuxia

2
@IanDunn I don't think modifying the globals directly is a good ideaอย่าบอกเรื่องนั้นกับผู้พัฒนาคอร์ wp;)
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 )

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.