问题描述

当我调用 switch_to_blog()的博客 ID,我不知道这个博客是否真的存在。该函数始终为 TRUE

测试用例:

switch_to_blog( PHP_INT_MAX );
$post = get_post( 1 );
restore_current_blog();

这将导致暴露给用户的数据库错误。我该如何防范?

现实世界用例

我是 Multilingual Press 的首席开发人员。当用户翻译帖子时,她会收到如下屏幕:

现在可能发生以下情况:

  1. 她成功保存了该帖子,并继续翻译该帖子。

  2. 另一位用户,网络管理员,在写作时会删除德文博客。

  3. 她再次点击保存并获取数据库错误。

我想避免这种情况。如果目标博客存在,我如何快速检查?我经常在多个不同的类别中调用 switch_to_blog(),所以它必须很快。

最佳解决方案

@ G.M. 缓存检查的想法导致我进行以下帮助函数。我将它放入全局命名空间,让它可以随处可见。

该功能不会对博客状态做任何说明,只要它存在并且没有标记为已删除。数据库查询非常快 (0.0001 秒),并且每个站点 id 只运行一个查询,无论调用该函数多长时间。

if ( ! function_exists( 'blog_exists' ) ) {

    /**
     * Checks if a blog exists and is not marked as deleted.
     *
     * @link   http://wordpress.stackexchange.com/q/138300/73
     * @param  int $blog_id
     * @param  int $site_id
     * @return bool
     */
    function blog_exists( $blog_id, $site_id = 0 ) {

        global $wpdb;
        static $cache = array ();

        $site_id = (int) $site_id;

        if ( 0 === $site_id )
            $site_id = get_current_site()->id;

        if ( empty ( $cache ) or empty ( $cache[ $site_id ] ) ) {

            if ( wp_is_large_network() ) // we do not test large sites.
                return TRUE;

            $query = "SELECT `blog_id` FROM $wpdb->blogs
                    WHERE site_id = $site_id AND deleted = 0";

            $result = $wpdb->get_col( $query );

            // Make sure the array is always filled with something.
            if ( empty ( $result ) )
                $cache[ $site_id ] = array ( 'do not check again' );
            else
                $cache[ $site_id ] = $result;
        }

        return in_array( $blog_id, $cache[ $site_id ] );
    }
}

用法

if ( ! blog_exists( $blog_id ) )
    return new WP_Error( '410', "The blog with the id $blog_id has vanished." );

参考文献

注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。