优化用于短码的查询

时间:2013-11-13 作者:Alex V.

所以,我有一个短码,它生成了所有已发布的多站点及其页面的列表。该网络大约有50个站点。问题是加载我放置了短代码的页面需要额外几秒钟的时间。因此,性能下降。想知道我能做些什么来优化这个。有什么想法?

<?php
class Multisite_Shortcode{

    /** Multisite parameters
    * network_id\'  = $wpdb->siteid,
    * site_order\'  = \'blog_id \', // blog_id, site_id, domain, path, registered, last_updated, public, archived, mature, spam, deleted, lang_id
    * site_sort\'   = \'ASC\', // ASC or DESC
    * public\'      = null,
    * archived\'    = null,
    * mature\'      = null,
    * spam\'        = null,
    * deleted\'     = null,
    * limit\'       = 100,
    * offset\'      = 0,

    ** pages parameters
    * depth\'       = 0,
    * child_of\'    = 0,
    * exclude\'     = \'\',
    * sort_column\' = \'menu_order, post_title\',
    * sort_order\'  = \'ASC\', // ASC or DESC
    * link_before\' = \'\',
    * link_after\'  = \'\',
    */

    /**
    * Shortcode initialization
    * @return void
    */
    function __construct() {
        add_shortcode( \'blog_pages\', array(&$this, \'shortcode_blog_pages\') );
    }

    function shortcode_blog_pages( $atts ) {
        global $wpdb;
        $args = shortcode_atts( array(
            // blog parameters
            \'network_id\' => $wpdb->siteid,
            \'site_order\' => \'blog_id \', // blog_id, site_id, domain, path, registered, last_updated, public, archived, mature, spam, deleted, lang_id
            \'site_sort\'  => \'ASC\',
            \'public\'     => null,
            \'archived\'   => null,
            \'mature\'     => null,
            \'spam\'       => null,
            \'deleted\'    => null,
            \'limit\'      => 100,
            \'offset\'     => 0,

            // pages parameters
            \'depth\'         => 0,
            \'child_of\'      => 0,
            \'exclude\'       => \'\',
            \'sort_column\'   => \'menu_order, post_title\',
            \'sort_order\'    => \'ASC\',
            \'link_before\'   => \'\',
            \'link_after\'    => \'\',
        ), $atts );

        $html = \'\';

        if ( wp_is_large_network() )
            return $html;

        $query = "SELECT * FROM $wpdb->blogs WHERE 1=1 ";

        if ( isset( $args[\'network_id\'] ) && ( is_array( $args[\'network_id\'] ) || is_numeric( $args[\'network_id\'] ) ) ) {
            $network_ids = implode( \',\', wp_parse_id_list( $args[\'network_id\'] ) );
            $query .= "AND site_id IN ($network_ids) ";
        }

        if ( isset( $args[\'public\'] ) )
            $query .= $wpdb->prepare( "AND public = %d ", $args[\'public\'] );

        if ( isset( $args[\'archived\'] ) )
            $query .= $wpdb->prepare( "AND archived = %d ", $args[\'archived\'] );

        if ( isset( $args[\'mature\'] ) )
            $query .= $wpdb->prepare( "AND mature = %d ", $args[\'mature\'] );

        if ( isset( $args[\'spam\'] ) )
            $query .= $wpdb->prepare( "AND spam = %d ", $args[\'spam\'] );

        if ( isset( $args[\'deleted\'] ) )
            $query .= $wpdb->prepare( "AND deleted = %d ", $args[\'deleted\'] );

        $query .= " ORDER BY {$args[\'site_order\']} {$args[\'site_sort\']} ";

        if ( isset( $args[\'limit\'] ) && $args[\'limit\'] ) {
            if ( isset( $args[\'offset\'] ) && $args[\'offset\'] )
                $query .= $wpdb->prepare( "LIMIT %d , %d ", $args[\'offset\'], $args[\'limit\'] );
            else
                $query .= $wpdb->prepare( "LIMIT %d ", $args[\'limit\'] );
        }

        $site_results = $wpdb->get_results( $query, ARRAY_A );

        $html = \'\';

        // Add other parameter to the list pages
        $args[\'echo\'] = false;
        $args[\'title_li\'] = \'\';
        $args[\'walker\'] = \'\';

        foreach( $site_results as $blog ) {
            switch_to_blog( $blog[\'blog_id\'] );
            $list_pages = @wp_list_pages( $args );
            restore_current_blog();

            $details = get_blog_details( array( \'blog_id\' => $blog[\'blog_id\'] ) );
            $title = "<a href=\'{$details->siteurl}\'>{$details->blogname}</a>";

            $html .= "<div id=\'site-pages-{$details->blog_id}\' class=\'site-pages\'>
                        <h2>$title</h2>
                        <ul>$list_pages</ul>
                    </div>";
        }

        return $html;
    }
}

new Multisite_Shortcode();
?>

2 个回复
SO网友:Pat J

我看到了一些您可以尝试简化操作的事情:

根据the Codex page for $wpdb->siteid. 此外,站点ID在wp配置中定义。php文件作为常量,BLOG_ID_CURRENT_SITE. 因此,任何参考$wpdb->siteid 可替换为BLOG_ID_CURRENT_SITE.

查看新的in-3.7功能wp_get_sites(). 它应该能够替换$query = "SELECT * FROM $wpdb->blogs WHERE 1=1 "; 等等

代替使用restore_current_blog() 之后switch_to_blog(), 您可以这样做:

$current_blog = get_current_blog_id();
foreach( $site_results as $blog ) {
    switch_to_blog( $blog );
    .
    .
    .
} // end of your foreach()
switch_to_blog( $current_blog );
如果我正确地阅读了您的代码,您应该能够替换任何$wpdb 用这两点打电话。看见this answer (第#3点)以及--“不要查询是否有模板标记来为您完成工作”。

参考文献wp_get_sites()
  • get_current_blog_id()
  • SO网友:Mark Kaplun

    您无法优化暴力代码。WordPress网络的设计并没有采用DB结构,这将使跨站点的高效查询成为可能。

    最好的解决方案是有一个站点选项,在其中存储网络上的所有页面(blog\\u id和post->id对),并在创建新页面或现有页面被丢弃时进行更新。

    结束

    相关推荐

    从wp_Query()中的特定类别中排除最近发布的帖子

    我有一个特色帖子滑块,它使用“特色”标签。我有一个关于这个的查询,它用这个标签抓取了最近的3篇文章,并在滑块中显示它们。下面,我列出了所有类别的10篇左右的最新帖子。我如何编写一个查询来排除带有“特色”标记的3篇最新帖子,因为它们已经在滑块中(不希望帖子重复),但当它们从滑块上掉下来时(即现在是第4篇最新的“特色”帖子等),它们会出现在帖子列表中?编辑:这是我的代码-我已经编写了一个快捷码,这样我就可以将其放入任何我想要的页面/小部件/等中,但获取3篇最新“特色”帖子的查询如下:posts_per_pag