web-dev-qa-db-ja.com

restore_current_blog()vs switch_to_blog()

switch_to_blog() のすべてのインスタンスの後に、現在の(実際には前の)ブログを復元するために restore_current_blog() を呼び出す必要があります。

しかし、2つ以上のブログをループして、それぞれでswitch_to_blog()を呼び出しているのであれば、ループの最後に追加のswitch_to_blog()を使用してオリジナルのブログに切り替えるのではなく、notがあります。各パスで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();
 }
22
Stephen Harris

そうでなければWPはswitch_to_blog()を呼び出すためにrestore_current_blog()を呼び出すたびに need が必要になり、誤ったデータを返す可能性があります。

両方の関数のソースコードを見ると、それらの関数が$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を作成するので、非常に重要な機能です。

参考までに、私はswitch_to_blog()を使ったプラグインを使ってこの問題に遭遇しました。このプラグインは、復元にrestore_current_blog()を使用せず、代わりに元のサイトに切り替えるためにswitch_to_blog()を使用しました。プラグインがアクティブな状態では、生成された私のサイトのURLはすべて間違っていました。

これが正しい使い方です。

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

複数のブログにまたがって実行したい場合は、毎回前のブログを復元する必要はありません。成長する唯一のものは$GLOBALS['_wp_switched_stack'] - ブログIDを持つ配列です。何も心配する必要はありません。

ただし、restore_current_blog()は2番目の切り替え後は機能しなくなります。これは、前のブログを使用しているためです。これはfirstblogではなく)です。最初のブログ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()を使用すると、切り替えに必要な時間が2倍になります。

16
fuxia

@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-includes/ms-blogs.php

1
T.Todua