WordPress分页失败或分页计算不准的原因-WordPress开发教程
今天在写个分类法功能,然后用到query_posts 和tax_query函数,查出分类筛选结果后发现,分页无论如何都不正常,比如我设置每页显示10条,一共有30条,正确的应该有三个分页,而实际查询
今天在写个分类法功能,然后用到query_posts 和tax_query函数,查出分类筛选结果后发现,分页无论如何都不正常,比如我设置每页显示10条,一共有30条,正确的应该有三个分页,而实际查询显示出的分页却是6页,第4/5/6页实际打开是显示没有结果的,为此,花费了我近两小时查找原因。下面记录解决此问题中更新到的知识点。
应该使用WP_Query而不是query_posts
WP_Query是WordPress自带的的一个用于处理复杂请求的类,是WordPress的主查询类,而query_posts函数官方则直接说明要尽量少用。
- 注意:query_posts函数将完全覆盖主查询,不适用于插件或主题。其过于简单的修改主查询的方法可能会有问题,应尽可能避免。在大多数情况下,有更好的,更高性能的选项来修改主查询,例如通过WP_Query中的'pre_get_posts'操作。
- query_posts()是一种改变WordPress用于显示帖子的主查询的方法。它通过将主查询放在一边,并用新查询替换它来完成此操作。要在调用query_posts后进行清理,请调用wp_reset_query(),并恢复原始主查询。
- 对于一般的帖子查询,请使用WP_Query或get_posts()。
理解wp查询功能
例如,在主页上,您通常会看到最新的10个帖子。如果你只想显示5个帖子(并且不关心分页),你可以像这样使用query_posts():
query_posts
– 您永远不应该使用query_posts
。除了上文所说的,query_posts
真正的大问题是,它破坏了主查询对象(存储在$wp_query
中)。很多插件和自定义代码都依赖于主查询对象,因此打破主查询对象意味着您打破了插件和自定义代码的功能。主函数影响分页功能,所以如果你打破了主要查询,就会破坏分页。
要证明query_posts
有多糟糕,请在任何模板上执行以下操作并比较结果
var_dump( $wp_query ); query_posts( '&posts_per_page=-1' ); var_dump( $wp_query );
get_posts
和WP_Query
是构建辅助查询(如静态首页上的相关文章,滑块,精选内容)的正确方法。应该注意的是,不应该在主页,单页或任何类型的归档页面上使用两者中的任何一个,因为它会破坏页面功能。如果需要修改主查询,请使用pre_get_posts
来完成,而不是自定义查询。
你可能忘记wp_reset_postdata了
wp_reset_postdata函数可将模板标记的上下文从辅助查询循环还原回主查询循环。这里的重点你要看好,是从辅助查询循环还原回主查询循环,这非常关键,也可以理解为为什么WordPress分页失败或计算不准确的原因,你使用了辅助查询,但却没有在查询完后还原回主查询,这样就造成了分页失败。
示例
标准循环
<?php // The Query $the_query = new WP_Query( $args ); // The Loop if ( $the_query->have_posts() ) { echo '<ul>'; while ( $the_query->have_posts() ) { $the_query->the_post(); echo '<li>' . get_the_title() . '</li>'; } echo '</ul>'; /* Restore original Post Data */ wp_reset_postdata(); } else { // no posts found }
多重循环
如果您有多个查询,则需要执行多个循环。像这样……
<?php // The Query $query1 = new WP_Query( $args ); if ( $query1->have_posts() ) { // The Loop while ( $query1->have_posts() ) { $query1->the_post(); echo '<li>' . get_the_title() . '</li>'; } /* Restore original Post Data * NB: Because we are using new WP_Query we aren't stomping on the * original $wp_query and it does not need to be reset with * wp_reset_query(). We just need to set the post data back up with * wp_reset_postdata(). */ wp_reset_postdata(); } /* The 2nd Query (without global var) */ $query2 = new WP_Query( $args2 ); if ( $query2->have_posts() ) { // The 2nd Loop while ( $query2->have_posts() ) { $query2->the_post(); echo '<li>' . get_the_title( $query2->post->ID ) . '</li>'; } // Restore original Post Data wp_reset_postdata(); } ?>
每页显示条数应该使用posts_per_page
在我查到的很多参考文章中,多数都在使用showposts来设置每页显示的条数,但在官方文档中明确说了:
- posts_per_page(int) – 每页显示的帖子数(自2.1版以来可用,替换了showposts参数)。使用'posts_per_page'=> – 1显示所有帖子('offset'参数被忽略,值为-1)。
目前最新版本已经是WordPress 5.1.1,应该跟上步伐。
正确使用paged分页参数
- paged(int) – 页数。使用“旧条目”链接显示通常在第X页上显示的帖子。
实例
// 每页显示3条数据 $query = new WP_Query( array( 'posts_per_page' => 3 ) ); // 在一个页面显示所有数据 $query = new WP_Query( array( 'posts_per_page' => -1 ) ); // 通过禁用分页显示所有数据 $query = new WP_Query( array( 'nopaging' => true ) ); // 显示第6页的数据 $query = new WP_Query( array( 'paged' => 6 ) );
显示当前页面中的帖子,并在未设置查询变量时将“paged”参数设置为1(第一页)。
$paged = ( get_query_var('paged') ) ? get_query_var('paged') : 1; $query = new WP_Query( array( 'paged' => $paged ) );
显示最近的一条最新的置顶数据,如果没有返回发布的最后一篇帖子:
$sticky = get_option( 'sticky_posts' ); $args = array( 'posts_per_page' => 1, 'post__in' => $sticky, 'ignore_sticky_posts' => 1, ); $query = new WP_Query( $args );
等等。
参考
- https://codex.wordpress.org/Class_Reference/WP_Query
- https://codex.wordpress.org/Function_Reference/wp_reset_postdata
- https://developer.wordpress.org/reference/functions/query_posts/
原创文章,作者:DavidWu,如若转载,请注明出处:https://www.davidwu.net/archives/122162

服务项目 | 服务内容 | 收费标准(元) |
---|---|---|
开发定制 | WordPress主题/插件开发定制 | (以最终需求为准) |
主题/插件汉化 | 汉化团队WordPress主题/插件,翻译率95% | (以标的主题/插件的句子数量为准) |
服务器环境配置 | 基于您现有服务器,搭建配置网站运行环境,结合我们多年来实战经验,可完美支持WordPress等PHP程序运行,并配置伪静态规则、优化目录权限等问题。服务器我们强烈推荐使用Linux系统。 | 100元/次 |
网站托管 | 若贵站目前尚无技术人员,无法完成服务器环境配置,可选择我们的网站托管服务,直接交付正常运行的WordPress站点,并且无需担心服务器的后续维护工作,一切都由我们来帮您完成。 | 标配套餐:1000元/年/站点 高配套餐:联系客服获取 |
网站加速优化 | 从服务器后端配置优化到WordPress数据库缓存、前端页面缓存、JS和CSS压缩合并,全方位优化网站加载速度,实现秒开。(此服务仅针对(云)服务器/VPS) | 500元/次(仅站内优化200元/次) |
主题配置 | 本站所有主题均支持,可快速实现,若有任何问题可以咨询客服解决,若您希望我们提供配置服务,可选购此服务。 | 英文主题安装 60元/次 汉化主题安装 30元/次 |
HTTPS配置 | HTTPS已经不断普及,并且有着更高的安全性以及SEO上的优待。该服务收取的为服务费,SSL证书产生的费用请自行承担。 | 100元/次 |
网站搬家 | 迁移网站所有文件和数据库信息、网站相关配置的调整、以及迁移中的疑难问题故障排除。 | 标准收费:500元/次 若网站数据量大,需协商 |
网站运维 | 提供整站的运维服务,保证网站正常运行。包含:网站故障定位及排除、网站数据备份和恢复、网站攻击及木马等问题的处理等 | 标准收费:2000元/年 IP 5000以上需协商 |