根据我的经验,使用\'posts_*\'
过滤器(\'posts_request\'
, \'posts_where\'
...) 结合str_replace
/ preg_replace
不可靠且不灵活:
不可靠,因为如果另一个过滤器修改使用其中一个过滤器,在更好的情况下会得到意外的结果,在最坏的情况下会出现SQL错误。
不灵活,因为更改参数(例如类别的“include\\u children”)或重用代码(例如3个术语而不是2个术语)需要大量工作。
此外,将代码调整为多站点兼容的代码需要手动编辑SQL。
因此,有时,如果evevn不是性能方面的最佳解决方案,那么更规范的方法就是最好的、更灵活的方法。
通过一些缓存技巧可以提高性能。。。
我的提议:
编写一个函数以供使用usort
要对来自不同查询的帖子进行排序(例如,每个学期一篇),请编写一个函数,在第一次运行时运行单独的查询、合并结果、排序、缓存并返回它们。在随后的请求中,只需返回缓存结果,即可在需要时处理缓存失效问题。首先,命令发布的函数:
function my_date_terms_posts_sort( Array $posts, $order = \'DESC\' ) {
if ( ! empty( $posts ) ) {
usort( $posts, function( WP_Post $a, WP_Post $b ) use ( $order ) {
$at = (int) mysql2date( \'U\', $a->post_date );
$bt = (int) mysql2date( \'U\', $b->post_date );
$orders = strtoupper($order) === \'ASC\' ? array( 1, -1 ) : array( -1, 1 );
return $at === $bt ? 0 : ( $at > $bt ) ? $orders[0] : $orders[1];
} );
}
return $posts;
}
然后,获取非缓存结果的函数:
function my_fresh_terms_get_posts( $args, $terms, $tax_query_args = NULL ) {
$posts = array();
// we need to know at least the taxonomy
if ( ! is_array( $tax_query_args ) || ! isset( $tax_query_args[\'taxonomy\'] ) ) return;
// handle base tax_query
$base_tax_query = isset( $args[\'tax_query\'] ) ? $args[\'tax_query\'] : array();
// run a query for each term
foreach ( $terms as $term ) {
$term_tax_query = wp_parse_args( array(
\'terms\' => array( $term ),
\'field\' => is_numeric( $term ) ? \'term_id\' : \'slug\'
), $tax_query_args );
$args[\'tax_query\'] = array_merge( $base_tax_query, array($term_tax_query) );
$q = new WP_Query( $args );
if ( $q->have_posts() ) {
// merging retrieved posts in $posts array
// preventing duplicates using ID as array keys
$ids = wp_list_pluck( $q->posts, \'ID\' );
$keyed = array_combine( $ids, array_values( $q->posts ) );
$posts += $keyed;
}
}
return $posts;
}
现在,检查缓存并返回它(如果可用)或返回非缓存结果的函数
function my_terms_get_posts( $args, $terms, $tax_query_args = NULL, $order = \'DESC\' ) {
// we need to know at least the taxonomy
if ( ! is_array( $tax_query_args ) || ! isset( $tax_query_args[\'taxonomy\'] ) ) return;
$tax = $tax_query_args[\'taxonomy\'];
// get cached results
$cached = get_transient( "my_terms_get_posts_{$tax}" );
if ( ! empty( $cached ) ) return $cached;
// no cached results, get \'fresh\' posts
$posts = my_fresh_terms_get_posts( $args, $terms, $tax_query_args );
if ( ! empty($posts) ) {
// order posts and cache them
$posts = my_date_terms_posts_sort( $posts, $order );
set_transient( "my_terms_get_posts_{$tax}", $posts, DAY_IN_SECONDS );
}
return $posts;
}
Cache is auto-cleaned daily, 但是,每次添加或更新特定分类法的新帖子时,都可能使其无效。可以在上添加清理缓存功能
\'set_object_terms\'
add_action( \'set_object_terms\', function( $object_id, $terms, $tt_ids, $taxonomy ) {
$taxonomies = get_taxonomies( array( \'object_type\' => array(\'post\') ), \'names\' );
if ( in_array( $taxonomy, (array) $taxonomies ) ) {
delete_transient( "my_terms_get_posts_{$taxonomy}" );
}
}, 10, 4 );
使用
// the number of post to retrieve for each term
// total of posts retrieved will be equat to this number x the number of terms passed
// to my_terms_get_posts function
$perterm = 5;
// first define general args:
$paged = ( get_query_var(\'paged\') ) ? get_query_var(\'paged\') : 1;
$args = array(
\'posts_per_page\' => $perterm,
\'paged\' => $paged,
);
// taxonomy args
$base_tax_args = array(
\'taxonomy\' => \'category\'
);
$terms = array( 9, 11 ); // is also possible to use slugs
// get posts
$posts = my_terms_get_posts( $args, $terms, $base_tax_args );
// loop
if ( ! empty( $posts ) ) {
foreach ( $posts as $_post ) {
global $post;
setup_postdata( $_post );
//-------------------------> loop code goes here
}
wp_reset_postdata();
}
函数足够灵活,可以使用复杂的查询,甚至可以查询其他分类:
E、 G。
$args = array(
\'posts_per_page\' => $perterm,
\'paged\' => $paged,
\'post_status\' => \'publish\',
\'tax_query\' => array(
\'relation\' => \'AND\',
array(
\'taxonomy\' => \'another_taxonomy\',
\'terms\' => array( \'foo\', \'bar\' ),
\'field\' => \'id\'
)
)
);
$base_tax_args = array(
\'taxonomy\' => \'category\',
\'include_children\' => FALSE
);
$terms = array( \'a-category\', \'another-one\' );
$posts = my_terms_get_posts( $args, $terms, $base_tax_args );
这样,“tax\\u query”设置在
$args
数组将与中的tax查询参数进行自动合并
$base_tax_args
, 对于
$terms
大堆
也可以按升序订购帖子:
$posts = my_terms_get_posts( $args, $terms, $base_tax_args, \'ASC\' );
请注意:
重要提示:如果某些帖子属于传递给函数的帖子中的多个类别(例如,在OP案例中,某些帖子同时具有类别9和11),则检索到的帖子数量将不是预期的数量,因为函数将在代码需要PHP 5.3时返回该帖子