有两种方法。超慢法和快速法
超慢方法这种方法很容易实现,但会给数据库带来巨大的负载,并可能导致严重的性能问题(以及严重减少可以同时访问站点的人数)。
这是post__not_in
论点I do not recommend using this. 我提到它只是为了完整性,因为不知道性能受到影响的人会推荐它。
为什么这么可怕
数据库查询是围绕着搜索你想要的而不是你不想要的内容构建的。
因此,如果在数据库级别排除posts,数据库有时会将整个posts表复制到内存中,删除要排除的行,然后执行查询。这是非常缓慢和昂贵的。
在我从事企业WordPress托管工作期间,我看到NOT IN
类型查询会使站点瘫痪,其方式可能是降低站点的运行速度,也可能是将站点的运行速度降低到无法使用的程度。移除它带来了巨大的改进。
危险在于,当在一个较小的测试站点上测试这些查询时,它们看起来并不慢,也不是很好,但还好。。。再加上多个用户同时访问该站点,会增加帖子和元表的大小,看起来不错的查询会增长到惊人的比例。
快速方法要求4篇帖子,然后过滤掉PHP中不需要的帖子。
This method is super fast.
例如:
$args = [
\'posts_per_page\' => 4,
];
$q = new WP_Query($args);
$count = 0;
while ( $q->have_posts() ) {
$q->the_post();
if ( $excluded_id === get_ID() ) {
continue;
}
$count += 1;
if ( $count > 3 ) {
break;
}
// ......
}
请注意,如果我们已经显示了3篇帖子,或者如果我们显示的帖子被排除在外,那么我们将中断/继续。
最后一点注意,上述内容也适用于以__not_in
, 他们的表现都很糟糕。另一个不适用于此用例的解决方案是使用数据来解决问题。例如,不是添加复选框以从主页隐藏帖子,而是添加一个名为show_on_homepage
这是默认添加的。
还要注意,while循环需要包装在if语句中,检查ifhave_posts
退货true
. 如果没有,那么就有一个bug,如果没有找到帖子,那么wp_reset_postdata()
在没有要重置的post数据时调用,从而干扰任何周围的post循环。
问题中的代码也缺少转义,因此容易受到HTML注入攻击。