restore_current_blog()vs switch_to_blog()


23

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

ただし、2つ以上のブログをループしてそれぞれを呼び出す場合は、各パスで呼び出すのではなく、ループの最後に追加を使用して元のブログに切り替えない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();
 }

今、私はこれを理解しています、私の答えを修正してくれてありがとう;)すべてを修正しています。
ブラソフィロ

回答:


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()するということは、私の代替アプローチは、関数が期待通りに動作せず、プラグインとコアを破壊する可能性があることを意味します。ありがとう
スティーブンハリス

1
これが当てはまる場合、Codexページrestore_current_blog()は更新が必要です。複数のスイッチについては、現在のファイルを保存してから$blog_id複数のswitch_to_blog()呼び出しを使用するだけでよいと書かれているためです。
パットJ

16

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

ただし、2回目の切り替え後は機能しなくなりますrestore_current_blog() (!!!)。以前のブログを使用するためです(最初のブログではないため)。したがって、最初のブログIDを保存し、呼び出します…

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

restore_current_blog()完了時ではなく。グローバル変数をリセットする必要があります。リセットしないと、@ user42826に記載されている問題が発生します。

パフォーマンスへの影響はhuge大です。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とコールをretriveしませんでしたswitch_to_blog()...コードソースを簡単に見て、コードの重複のビットがありますようです-
スティーブン・ハリス

3
グローバルを直接変更することは良い考えだとは思いません。なぜなら、コードをCoreの内部に結合しているからです。APIを適切に使用することをお勧めします。
イアン・ダン

2
@IanDunn記録のためだけに:switch_to_blog()とにかく非常に限られた(壊れた)APIです。WordPressがこれを修正した場合、コードをリファクタリングする必要があります。そして、WordPressは愛するグローバルを決してgiveめません。
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-includes / ms-blogs.php

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.