与相关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\'] );
在最后我的问题是:方法#2是符合WordPress开发最佳实践,还是一个丑陋的黑客行为?
我的测试将以下代码添加到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)
}
很抱歉这么冗长,但我想确定我这里有所有的东西。
最合适的回答,由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()的位置和方式。