switch_to_blog()
的每个实例之后,您应该调用restore_current_blog()
来还原当前(实际上是先前的)博客。 但是,如果您要遍历两个或多个博客并在每个博客上调用
switch_to_blog()
,是否有理由不在循环结束时不使用其他switch_to_blog()
来切换到原始博客,而不是调用每次通过restore_current_blog()
。 br /> $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 );
#1 楼
在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']
是非空的,即使您使用switch_to_blog()
切换回原始博客,WP也会认为它处于切换模式。开关模式功能是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()的存在意味着我的替代方法导致该函数无法正常运行,并且可能会破坏插件以及核心。谢谢
–斯蒂芬·哈里斯(Stephen Harris)
13年11月17日在22:59
如果是这样,则restore_current_blog()的Codex页面需要更新,因为它说对于多个开关,只需保存当前的$ blog_id,然后使用多个switch_to_blog()调用。
– Pat J
13年11月21日在16:54
#2 楼
如果要运行多个博客,则无需每次都还原以前的博客。唯一增长的是$GLOBALS['_wp_switched_stack']
–一个具有博客ID的数组,没什么好担心的。以前的博客-而不是第一个博客。因此,存储第一个博客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()
会使切换所需的时间加倍。评论
认为没有任何理由不这样做。感到困惑的是,为什么restore_current_blog()不只是检索以前的博客ID并调用switch_to_blog()-简要查看代码源,似乎有一些代码重复...
–斯蒂芬·哈里斯(Stephen Harris)
13年3月2日在20:52
我不认为直接修改全局变量不是一个好主意,因为您会将代码耦合到Core的内部,这不是面向未来的。最好正确使用API。
–伊恩·邓恩
2014年9月29日在17:17
@IanDunn仅作记录:switch_to_blog()是一个非常有限的(损坏的)API。如果WordPress可以解决此问题,则无论如何我们都必须重构代码。 WordPress永远不会放弃其心爱的全球客户。
– fuxia♦
2015年2月2日,0:54
@IanDunn我不认为直接修改全局变量是一个好主意,不要告诉wp核心开发人员;)
– Ejaz
16-2-2在19:14
@ J.D。当然,您需要了解上下文。对于已经切换的状态,您甚至可能必须维护正确的堆栈索引。我可能会寻找避免这种情况的方法。另一方面,这是WordPress,因此可能没有其他方法……
– fuxia♦
16年7月20日在19:28
#3 楼
感谢@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)
评论
现在我明白了,感谢您纠正了我的回答;)我正在修改所有内容。