restore_current_blog () vs switch_to_blog ()

23

Setelah setiap contoh dari switch_to_blog()Anda harus menelepon restore_current_blog()untuk mengembalikan blog saat ini (sebenarnya, sebelumnya).

Tetapi jika Anda mengulang dua atau lebih blog dan memanggil switch_to_blog()masing-masing, apakah ada alasan untuk tidak menggunakan tambahan switch_to_blog()di akhir loop untuk beralih ke blog asli daripada menelepon restore_current_blog()di setiap pass.

Misalnya

Kenapa tidak:

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

dari pada:

 foreach( $blog_ids as $blog_id ){
    switch_to_blog( $blog_id );
    //Do stuff
    restore_current_blog_id();
 }
Stephen Harris
sumber
Sekarang saya mengerti ini, terima kasih telah memperbaiki jawaban saya;) Saya merevisi semuanya.
brasofilo

Jawaban:

19

Setelah setiap contoh switch_to_blog()Anda perlu menelepon restore_current_blog()sebaliknya WP akan berpikir itu dalam mode "switched" dan berpotensi dapat mengembalikan data yang salah.

Jika Anda melihat kode sumber untuk kedua fungsi tersebut, Anda akan melihat fungsi-fungsi itu mendorong / memunculkan data menjadi global $GLOBALS['_wp_switched_stack']. Jika Anda tidak menelepon restore_current_blog()setelah setiap switch_to_blog(), $GLOBALS['_wp_switched_stack']akan kosong. Jika $GLOBALS['_wp_switched_stack']WP non-kosong berpikir itu dalam mode yang diaktifkan, bahkan jika Anda beralih kembali ke blog asli menggunakan switch_to_blog(). Fungsi mode yang diaktifkan adalah ms_is_switched()dan itu memengaruhi wp_upload_dir(). Jika wp_upload_dir()dianggap berada dalam mode switched, itu dapat mengembalikan data yang salah. wp_upload_dir()membangun URL untuk situs, jadi itu adalah fungsi yang sangat kritis.

Ini adalah penggunaan yang benar:

 foreach( $blog_ids as $blog_id ){
    switch_to_blog( $blog_id );
    //Do stuff
    restore_current_blog();
 }
pengguna42826
sumber
Terima kasih, saya tidak punya kesempatan untuk bekerja melalui sup konstanta & logika yang wp_upload_dir()mempekerjakan untuk menghasilkan url, tapi saya akan mengambil kata-kata Anda bahwa ini memang mengakibatkan perilaku buggy. Bagaimanapun, keberadaan ms_is_switched()berarti pendekatan alternatif saya menghasilkan fungsi tidak berperilaku seperti yang diharapkan dan dapat merusak plug-in serta inti. Terima kasih
Stephen Harris
1
Jika ini benar, maka halaman Codex untuk restore_current_blog()memerlukan pembaruan, karena dikatakan bahwa untuk beberapa switch, satu hanya perlu menyimpan saat ini $blog_iddan kemudian menggunakan beberapa switch_to_blog()panggilan.
Pat J
16

Jika Anda ingin menjalankan beberapa blog, Anda tidak perlu mengembalikan blog sebelumnya setiap kali. Satu-satunya hal yang tumbuh adalah $GLOBALS['_wp_switched_stack']- array dengan ID blog, tidak perlu khawatir.

Tapi perlu diingat, restore_current_blog() tidak akan berfungsi (!!!) Lagi setelah beralih kedua, karena menggunakan blog sebelumnya - yang bukan blog pertama saat itu. Jadi simpan ID blog pertama, dan hubungi ...

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

... bukannya restore_current_blog()saat Anda selesai. Variabel global harus disetel ulang, atau Anda akan mengalami masalah yang disebutkan oleh @ user42826.

Dampak kinerja sangat besar. Saya telah menjalankan beberapa tes pada instalasi lokal dengan 12 situs:

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

Hasil:

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

Menggunakan restore_current_blog()setelah setiap saklar menggandakan waktu yang dibutuhkan hanya untuk beralih.

fuxia
sumber
Kupikir tidak ada alasan untuk tidak melakukannya. Bingung mengapa restore_current_blog()tidak hanya membuka kembali ID dan panggilan blog sebelumnya switch_to_blog()- melihat sekilas sumber kode dan sepertinya ada sedikit duplikasi kode ...
Stephen Harris
3
Saya tidak berpikir memodifikasi global secara langsung adalah ide yang bagus, karena Anda menggabungkan kode Anda ke internal Core, yang bukan merupakan bukti masa depan. Lebih baik menggunakan API dengan benar.
Ian Dunn
2
@IanDunn Hanya sebagai catatan: switch_to_blog()API yang sangat terbatas (rusak). Jika WordPress pernah perbaikan yang , kita harus refactor kode kita pula. Dan WordPress tidak akan pernah menyerah global tercinta.
fuxia
2
@IanDunn I don't think modifying the globals directly is a good idea, jangan katakan itu kepada pengembang inti wp;)
Ejaz
1
@ JK Tentu saja, Anda harus sadar konteks. Dalam kasus keadaan yang sudah diaktifkan, Anda mungkin harus mempertahankan indeks tumpukan yang benar. Saya mungkin akan mencari cara untuk menghindari itu. Di sisi lain, ini adalah WordPress, jadi mungkin tidak ada cara lain ...
fuxia
1

Terima kasih atas jawaban @toscho. Permintaan ini dalam antrian WP - lihat pembaruan di sini . Sampai yang diperbaiki di WP, jika ada yang sangat ingin menggunakan standar restore_current_blog(), maka di sini adalah metode lain (tolong perbaiki jika saya salah):

membuat fungsi Anda, yaitu

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

}

dan jalankan hanya sekali ketika Anda menyelesaikan beberapa switch Anda. (selengkapnya: wp-include / ms-blogs.php )

T.Todua
sumber