RESTORE_CURRENT_BLOG()与MULTIME SWITCH_TO_BLOG(),然后删除$GLOBALS[‘_wp_Switched_Stack’]

时间:2013-11-21 作者:Pat J

与相关this answer, 哪些国家

每次switch_to_blog()need 调用restore_current_blog() 否则,WP会认为它处于“切换”模式,并可能返回不正确的数据。

我已经做了一些测试,可以确认这是一个问题。(它还回答了我在工作中遇到的一个关于文件上传URL的问题,对此我竖起大拇指。)

在我的测试(详情如下)中,我发现有两种方法可以继续:

始终配对switch_to_blog() 具有restore_current_blog()switch_to_blog(), 最后一个切换回你开始的博客unset( $GLOBALS[\'_wp_switched_stack\'] ); 在最后

我的测试将以下代码添加到functions.php 在我的一个WordPress多站点安装上:

add_action( \'shutdown\', \'pj_stb_test\' );
function pj_stb_test() {
    if( ! current_user_can( \'update_core\' ) )
        return;

    $home = get_current_blog_id();
    $checklist = array(
        \'constants\' => array( \'UPLOADS\', \'MULTISITE\', \'BLOGUPLOADDIR\' ),
        \'functions\' => array( \'ms_is_switched\', \'wp_upload_dir\' ),
    );
    $site_ids = array( 1, 2, 3 );

    echo( "switch_to_blog() chain:<br />" );
    foreach( $site_ids as $id ) {
        switch_to_blog( $id );
    }
    switch_to_blog( $home );
    _pj_dump( $checklist );

    echo( \'switch_to_blog() chain followed by 
           unset( $GLOBALS[\\\'_wp_switched_stack\\\'] )<br />\' );
    foreach( $site_ids as $id ) {
        switch_to_blog( $id );
    }
    switch_to_blog( $home );
    unset( $GLOBALS[\'_wp_switched_stack\'] );
    _pj_dump( $checklist );

    echo( \'switch_to_blog() / restore_current_blog() pairings<br />\' );
    foreach( $site_ids as $id ) {
        switch_to_blog( $id );
        restore_current_blog();
    }
    _pj_dump( $checklist );

function _pj_dump( $checklist ) {
    $constants = $checklist[\'constants\'];
    $functions = $checklist[\'functions\'];
    echo( "<p>Constants:</p>" );
    echo( "<pre>\\n" );
    foreach( $constants as $c ) {
        echo( $c . \': \' );
        var_dump( constant( $c ) );
        echo( "\\n" );
    }
    foreach( $functions as $f ) {
        echo( $f . \': \' );
        var_dump( call_user_func( $f ) );
        echo( "\\n" );
    }
}
在我的网络中的任意站点上返回的输出:

switch_to_blog() chain:
UPLOADS: string(30) "wp-content/blogs.dir/94/files/"
MULTISITE: bool(true)
BLOGUPLOADDIR: string(50) "/path/to/wp/wp-content/blogs.dir/94/files/"
ms_is_switched: bool(true)
wp_upload_dir: array(6) {
  ["path"]=>
  string(57) "/path/to/wp/wp-content/blogs.dir/94/files/2013/11"
  ["url"]=>
  string(74) "http://example.com/my-site/wp-content/blogs.dir/94/files/2013/11"
  ["subdir"]=>
  string(8) "/2013/11"
  ["basedir"]=>
  string(49) "/path/to/wp/wp-content/blogs.dir/94/files"
  ["baseurl"]=>
  string(66) "http://example.com/my-site/wp-content/blogs.dir/94/files"
  ["error"]=>
  bool(false)
} 

switch_to_blog() chain followed by unset( $GLOBALS[\'_wp_switched_stack\'] )
UPLOADS: string(30) "wp-content/blogs.dir/94/files/"
MULTISITE: bool(true)
BLOGUPLOADDIR: string(50) "/path/to/wp/wp-content/blogs.dir/94/files/"
ms_is_switched: bool(false)
wp_upload_dir: array(6) {
  ["path"]=>
  string(57) "/path/to/wp/wp-content/blogs.dir/94/files/2013/11"
  ["url"]=>
  string(50) "http://example.com/my-site/files/2013/11"
  ["subdir"]=>
  string(8) "/2013/11"
  ["basedir"]=>
  string(49) "/path/to/wp/wp-content/blogs.dir/94/files"
  ["baseurl"]=>
  string(42) "http://example.com/my-site/files"
  ["error"]=>
  bool(false)
} 

switch_to_blog() / restore_current_blog() pairings
UPLOADS: string(30) "wp-content/blogs.dir/94/files/"
MULTISITE: bool(true)
BLOGUPLOADDIR: string(50) "/path/to/wp/wp-content/blogs.dir/94/files/"
ms_is_switched: bool(false)
wp_upload_dir: array(6) {
  ["path"]=>
  string(57) "/path/to/wp/wp-content/blogs.dir/94/files/2013/11"
  ["url"]=>
  string(50) "http://example.com/my-site/files/2013/11"
  ["subdir"]=>
  string(8) "/2013/11"
  ["basedir"]=>
  string(49) "/path/to/wp/wp-content/blogs.dir/94/files"
  ["baseurl"]=>
  string(42) "http://example.com/my-site/files"
  ["error"]=>
  bool(false)
}
很抱歉这么冗长,但我想确定我这里有所有的东西。

1 个回复
最合适的回答,由SO网友:user42826 整理而成

简言之,答案是否定的。这是一个丑陋的黑客=)影响的全局变量比你正在处理的变量多。以下是我发现受影响的全局变量:$wpdb、$wp\\u角色、$wp\\u对象\\u缓存、$global\\u组、$globals[\'\\u wp\\u switched\\u stack\']、$globals[\'blog\\u id\']和$globals[\'table\\u prefix\']。可能还有更多。我发现$wpdb是另一个主要变量,它被switch\\u to\\u blog()更改。在测试中尝试var\\u dump\'ing$wpdb,您将看到效果。如果您不“始终将switch\\u to\\u blog()与restore\\u current\\u blog()配对”,任何依赖于这些全局变量的API都可能受到影响

长的回答是“视情况而定”我想说的是,“在每个switch\\u to\\u blog()实例之后,您需要调用restore\\u current\\u blog()”这句话是最佳实践,通常是正确的。但在某些情况下,您不需要返回原始博客或还原\\u current\\u blog()。例如,我创建了一个管理插件,它改变了所有博客中的用户角色。它使用switch\\u to\\u blog遍历了网络中的所有博客,调用了其他WP API(不依赖于这些全局API),并立即结束。因此,无需还原\\u current\\u blog()。YMMV取决于使用switch\\u to\\u blog()的位置和方式。

结束

相关推荐

Copy Root Multisite Site

我在WordPress中创建了一个多站点安装,位于example.com 网站位于example.com/site1, example.com/site2 等是否可以创建example.com 在example.com/site3?Blog Copier 和NS cloner 由于某种原因,不允许您创建根站点的副本。这背后的技术限制是什么?