使用无缓存错误的直接数据库调用

时间:2016-05-14 作者:Cedon

我有一个自定义函数,可以根据数据库中第一篇和最后一篇文章的年份创建动态版权年份范围:

function jldc_copyright_dates() {
    global $wpdb;
    $copyright_dates = $wpdb->get_results( "
        SELECT
            YEAR(min(post_date_gmt)) as firstdate,
            YEAR(max(post_date_gmt)) as lastdate
        FROM
            $wpdb->posts
    " );

    if ( $copyright_dates ) {
        $copyright_year = $copyright_dates[0]->firstdate;
        if ( $copyright_dates[0]->firstdate !== $copyright_dates[0]->lastyear ) {
            $copyright_year .= \'—\' . $copyright_dates[0]->lastdate;
        }
        echo esc_html( $copyright_year . \' \'; );
    }
}
我正在将PHPC与WordPress VIP代码标准一起使用,当我在此文件上运行它时,我得到一个警告:Usage of a direct database call is discouraged.

此外,我还得到一个错误Usage of a direct database call without caching is prohibited. Use wp_cache_get / wp_cache_set or wp_cache_delete.

我该如何进行测试以查看这些值是否已缓存,如果未缓存,则缓存它们以消除此错误?

1 个回复
SO网友:TheDeadMedic

我同意@Tom J Nowell的观点:

我建议你把它删除,或者干脆说“版权所有”。

但在寻找答案的过程中,有一条建议使用选项字段来缓存年份:

/**
 * Get year range for posts.
 * 
 * @return str
 */
function wpse_226627_get_copyright() {
    if ( ! $years = get_option( \'copyright\' ) ) {
        $args = [
            \'posts_per_page\' => 1,
            \'post_type\'      => get_post_types([ \'public\' => true ]),
            \'post_status\'    => \'publish\',
            \'orderby\'        => \'post_date\',

            /**
             * Don\'t waste memory we don\'t need
             */
            \'update_post_term_cache\' => false,
            \'update_post_meta_cache\' => false,
            \'cache_results\'          => false,
        ];

        $newest = get_posts([ \'order\' => \'DESC\' ] + $args );
        $oldest = get_posts([ \'order\' => \'ASC\'  ] + $args );
        $years  = [
            \'from\' => $oldest ? mysql2date( \'Y\', $oldest[0]->post_date_gmt ) : \'\',
            \'to\'   => $newest ? mysql2date( \'Y\', $newest[0]->post_date_gmt ) : \'\',
        ];

        update_option( \'copyright_years\', $years );
    }

    return $years;
}

/**
 * Bust the cache.
 */
function wpse_226627_flush_years( $post_id ) {
    if ( in_array( get_post_type( $post_id ), get_post_types([ \'public\' => true ]) ) )
        update_option( \'copyright_years\', \'\' );
}

add_action( \'before_delete_post\', \'wpse_226627_flush_years\' );
add_action( \'save_post\',          \'wpse_226627_flush_years\' );
这样会刷新缓存;只有在创建/更新/删除帖子时才会填充,所以这里只需几个额外的查询(而不是一个直接的数据库调用)就没有什么大不了的了。

$years     = wpse_226627_get_years();
$copyright = $years[\'from\'];
if ( $years[\'from\'] != $years[\'to\'] )
    $copyright .= \' — \' . $years[\'to\'];
我选择将年份缓存为一个序列化数组(而不是编译的版权字符串),这样,如果您希望更改它们的布局/使用它们做一些不同的事情,您就可以始终独立使用这些值。

相关推荐

Save URL into database

我提前道歉。我甚至不知道怎么问,问什么,搜索什么。假设用户可以从不同的URL访问我的网站。https://www.mywebsite.com/something1 https://www.mywebsite.com/something2 https://www.mywebsite.com/something3我怎么能把那些“东西”save into DB? 或者以其他方式store 那些“某物”变量。我想有所有尝试访问我的网站的概述。我能做什么?有什么想法吗?