如何将PHP foreach循环转换为WP_Query?自定义表查询问题
问题分析与解决方案
首先得指出你代码里的核心误区:WP_Query是用来查询WordPress自带的帖子/自定义帖子类型的,根本不能直接用来查询你自己创建的kv_beoordelingen自定义数据库表。你把自定义表的行对象$beoordeling传给post_type参数,完全不符合WP_Query的用法,这就是代码失效的原因。
下面给你两种针对性的解决方案,根据你的需求选择:
方案一:保留自定义表,实现分页功能(快速适配)
如果你不想改动现有数据库结构,只想给当前的自定义表查询加上分页和条目控制,可以用$wpdb配合WordPress的分页参数来实现,代码如下:
<?php global $wpdb; $table_name = $wpdb->prefix . "kv_beoordelingen"; // 配置分页参数 $posts_per_page = 10; // 自定义每页显示的条目数,替换成你想要的数值 $paged = get_query_var('paged') ? get_query_var('paged') : 1; $offset = ($paged - 1) * $posts_per_page; // 获取总条目数,用于计算分页页数 $total_beoordelingen = $wpdb->get_var("SELECT COUNT(*) FROM `{$table_name}`"); // 安全查询当前页的数据(用prepare防止SQL注入) $beoordelingen = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM `{$table_name}` ORDER BY `dateSince` DESC LIMIT %d OFFSET %d", $posts_per_page, $offset ) ); if ($beoordelingen) { // 循环输出每条评价 foreach ($beoordelingen as $beoordeling) { $beschrijving = $beoordeling->description; if ($beschrijving) { // 用esc_html转义内容,防止XSS攻击 echo "<p><strong>Ervaring</strong><br/>" . esc_html($beschrijving) . "</p>"; } } // 生成分页导航(如果总页数大于1) $total_pages = ceil($total_beoordelingen / $posts_per_page); if ($total_pages > 1) { echo '<div class="pagination">'; echo paginate_links(array( 'base' => get_pagenum_link(1) . '%_%', 'format' => 'page/%#%/', 'current' => max(1, $paged), 'total' => $total_pages, 'prev_text' => __('« Vorige'), 'next_text' => __('Volgende »'), )); echo '</div>'; } } else { echo "Geen beoordelingen beschikbaar"; } ?>
方案一要点:
- 用
$wpdb->prepare处理查询,避免SQL注入风险 - 借助WordPress内置的
paginate_links()生成标准分页导航,无需自己写链接逻辑 - 通过
$posts_per_page轻松控制每页显示的条目数
方案二:迁移为自定义帖子类型(推荐,贴合WordPress生态)
如果你的评价数据适合纳入WordPress的内容体系,推荐把kv_beoordelingen的数据迁移为自定义帖子类型,这样就能完全用WP_Query来处理分页和查询,后续维护扩展也更方便。
步骤1:注册自定义帖子类型(放到主题的functions.php里)
function register_beoordeling_post_type() { $args = array( 'public' => false, // 如果不需要在前台公开展示,设为false;需要的话改成true 'label' => 'Beoordelingen', 'supports' => array('custom-fields'), // 用来存储你的description字段 'rewrite' => array('slug' => 'beoordelingen'), // 自定义URL slug ); register_post_type('beoordeling', $args); } add_action('init', 'register_beoordeling_post_type');
步骤2:一次性迁移数据(执行后可以删除这段代码)
<?php global $wpdb; $table_name = $wpdb->prefix . "kv_beoordelingen"; $beoordelingen = $wpdb->get_results("SELECT * FROM `{$table_name}`"); foreach ($beoordelingen as $beoordeling) { // 创建帖子 $post_id = wp_insert_post(array( 'post_type' => 'beoordeling', 'post_title' => 'Beoordeling ' . $beoordeling->id, // 可以改成更有意义的标题 'post_status' => 'publish', 'post_date' => $beoordeling->dateSince, // 保留原来的日期 )); if ($post_id) { // 把description字段存储为自定义字段 update_post_meta($post_id, 'beschrijving', $beoordeling->description); // 如果还有其他字段,也用update_post_meta一起存储 } } echo "数据迁移完成!"; ?>
步骤3:用WP_Query查询并分页
<?php $paged = get_query_var('paged') ? get_query_var('paged') : 1; $beoordeling_query = new WP_Query(array( 'post_type' => 'beoordeling', 'posts_per_page' => 10, // 每页条目数 'order' => 'DESC', 'orderby' => 'date', 'paged' => $paged, )); if ($beoordeling_query->have_posts()) : while ($beoordeling_query->have_posts()) : $beoordeling_query->the_post(); // 获取自定义字段里的描述内容 $beschrijving = get_post_meta(get_the_ID(), 'beschrijving', true); if ($beschrijving) { echo "<p><strong>Ervaring</strong><br/>" . esc_html($beschrijving) . "</p>"; } endwhile; // 生成分页导航 echo '<div class="pagination">'; echo paginate_links(array( 'total' => $beoordeling_query->max_num_pages, 'current' => max(1, $paged), 'prev_text' => __('« Vorige'), 'next_text' => __('Volgende »'), )); echo '</div>'; wp_reset_postdata(); // 重置查询,避免影响后续内容 else : echo "Geen beoordelingen beschikbaar"; endif; ?>
方案二优势:
- 完全利用WordPress内置功能,无需自己处理数据库底层逻辑
- 可以在WordPress后台直接管理这些评价(如果设置
public为true) - 更容易扩展,比如添加分类、标签,或者用插件增强功能
内容的提问来源于stack exchange,提问作者Justus
相关产品推荐
相关产品推荐

