But if you're looping through two or more blogs and calling switch_to_blog() on each, is there any reason not to use an additional switch_to_blog() at the end of the loop to switch to the original blog rather than calling restore_current_blog() at each pass.

2 Answers
2

After every instance of switch_to_blog() you need to call restore_current_blog() otherwise WP will think it is in a "switched" mode and can potentially return incorrect data.

If you view the source code for both functions you will see those functions push/pop data into a global called $GLOBALS['_wp_switched_stack']. If you do not call restore_current_blog() after every switch_to_blog(), $GLOBALS['_wp_switched_stack'] will be non-empty. If $GLOBALS['_wp_switched_stack'] is non-empty WP thinks it is in a switched mode, even if you switched back to the original blog using switch_to_blog(). The switched mode function is ms_is_switched() and it affects wp_upload_dir(). If wp_upload_dir() thinks it is in a switched mode, it can return data that is incorrect. wp_upload_dir() builds URLs for the site, so it is a very critical function.

FYI, I ran into this problem using a plugin that used switch_to_blog(). The plugin did not use restore_current_blog() to restore, instead it used switch_to_blog() to switch back to the original site. With the plugin active, all my site urls that were generated were incorrect.

Thanks, I've not had chance to work through the soup of constants & logic that wp_upload_dir() employs to generate urls, but I shall take your word that this does indeed result in buggy behaviour. In any case, the existence of ms_is_switched() means my alternative approach results in the function not behaving as expected and could break plug-ins as well as core. Thanks
–
Stephen HarrisNov 17 '13 at 22:59

1

If this is true, then the Codex page for restore_current_blog() needs an update, since it says that for multiple switches, one need only save the current $blog_id and then use multiple switch_to_blog() calls.
–
Pat JNov 21 '13 at 16:54

If you want to run over multiple blogs there is no need to restore the previous blog each time. The only thing that grows is $GLOBALS['_wp_switched_stack'] – an array with blog IDs, nothing to worry about.

But keep in mind, restore_current_blog() will not work anymore after the second switch, because it uses the previous blog – which is not the first blog then. So store the first blog ID, and call …

Thought there wasn't any reason not to. Was confused why restore_current_blog() didn't just retrive the previous blog ID and call switch_to_blog() - a brief look at the code source and it seems there's a bit of code duplication...
–
Stephen HarrisMar 2 '13 at 20:52

great info. Didn´t know that . Maybe restore_current_blog() should have switched the name to restore_previous_blog(). or maybe change the whole function´s own functionality to operate as a real restore_main_blog(). trac material.
–
krembo99Apr 11 '13 at 3:52

One more thing needs to be set as well: $GLOBALS['switched'] = false;. Although the function ms_is_switched() do check for $GLOBALS['_wp_switched_stack'] but this is introduced since 3.5 and some plugins are still using $GLOBALS['switched'] to see if WP is in switched mode or not.
–
ParhamJan 28 '14 at 10:14

I don't think modifying the globals directly is a good idea, because you're coupling your code to Core's internals, which isn't future-proof. It's better to use the API properly.
–
Ian DunnSep 29 '14 at 17:17