0

0

WooCommerce 自定义 WP_Query 获取订单详情报错解决方案

心靈之曲

心靈之曲

发布时间:2025-10-08 10:04:22

|

204人浏览过

|

来源于php中文网

原创

woocommerce 自定义 wp_query 获取订单详情报错解决方案

本文旨在解决在使用自定义 WP_Query 获取 WooCommerce 订单详情时遇到的 500 错误以及数据获取失败的问题。通过分析错误原因,提供了优化后的代码示例,并详细解释了如何正确地使用 WP_Query 来实现订单数据的分页加载和展示,避免常见的错误和陷阱。

在使用 WP_Query 获取 WooCommerce 订单详情时,可能会遇到一些问题,例如服务器返回 500 错误,或者查询结果为空。这些问题通常与查询参数设置不正确、循环使用方式不当,以及对 WooCommerce 对象的使用方式有关。下面将详细介绍如何解决这些问题,并提供一个可用的代码示例。

问题分析

  1. 500 错误: 500 错误通常表示服务器内部错误。在使用 WP_Query 时,如果在循环内部尝试获取订单 ID 或者订单项目时出现问题,可能是因为 $post 对象没有正确设置。
  2. 查询结果为空: 即使没有 500 错误,查询结果也可能为空。这可能是因为查询参数设置不正确,例如 post_type 或 post_status 设置错误,或者分页参数没有正确传递。

解决方案

1. 正确设置 WP_Query 参数

确保 WP_Query 的参数设置正确,特别是 post_type 和 post_status。对于 WooCommerce 订单,post_type 应该是 shop_order,post_status 应该是 wc-completed 或其他订单状态。此外,为了实现分页,需要正确设置 posts_per_page 和 paged 参数。

$paged = max( 1, intval( $_POST[ 'page' ] ) ); // 确保页码大于等于 1
$per_page = 4; // 每页显示的订单数量

$args = array(
    'post_type'      => 'shop_order',
    'post_status'    => 'wc-completed',
    'orderby'        => 'post_date',
    'order'          => 'DESC',
    'posts_per_page' => $per_page,
    'paged'          => $paged,
);

$loop = new WP_Query( $args );

2. 正确使用 the_post() 函数

在 WP_Query 的循环内部,必须调用 the_post() 函数来设置 $post 对象。这使得可以使用 get_the_ID() 函数获取当前订单的 ID。

if ( $loop->have_posts() ) {
    while ( $loop->have_posts() ) {
        $loop->the_post();

        $order_id = get_the_ID(); // 正确获取订单 ID
        $order = wc_get_order( $order_id ); // 使用订单 ID 获取 WC_Order 对象

        // ... 其他代码 ...
    }
    wp_reset_postdata(); // 重置 $post 对象,避免影响其他查询
}

3. 获取订单详情

获取订单详情需要使用 WC_Order 对象。通过 wc_get_order() 函数,可以使用订单 ID 获取 WC_Order 对象,然后使用该对象的方法来获取订单的各种信息,例如订单状态、订单项目、总金额等。

社研通
社研通

文科研究生的学术加速器

下载
$order = wc_get_order( $order_id );

if ( $order ) {
    $orders_id = $order->get_id(); // 获取订单 ID
    $status = wc_get_order_status_name( $order->get_status() ); // 获取订单状态名称
    $date_created = $order->get_date_created()->date( 'd/m/Y' ); // 获取订单创建日期
    $payment_method = $order->get_payment_method_title(); // 获取支付方式名称
    $order_total = $order->get_formatted_order_total(); // 获取格式化的订单总金额

    $items = $order->get_items(); // 获取订单项目
    foreach ( $items as $item ) {
        $product_name = $item->get_name(); // 获取产品名称
        $product_id = $item->get_product_id(); // 获取产品ID
        $product = wc_get_product( $product_id ); // 获取产品对象
        if($product){
            $product_image = $product->get_image(); // 获取产品图片
        }
        // ... 其他代码 ...
    }
}

4. 完整代码示例

下面是一个完整的代码示例,展示了如何使用 WP_Query 获取 WooCommerce 订单详情,并进行分页显示:

add_action( 'wp_ajax_demo_pagination_posts', 'demo_pagination_posts' );
add_action( 'wp_ajax_nopriv_demo_pagination_posts', 'demo_pagination_posts' );

function demo_pagination_posts() {
    global $wpdb;
    $msg = '';

    if ( isset( $_POST[ 'page' ] ) ) {
        $paged = max( 1, intval( $_POST[ 'page' ] ) );
        $per_page = 4;

        $args = array(
            'post_type'      => 'shop_order',
            'post_status'    => 'wc-completed',
            'orderby'        => 'post_date',
            'order'          => 'DESC',
            'posts_per_page' => $per_page,
            'paged'          => $paged,
        );

        $loop = new WP_Query( $args );
        $count = $loop->found_posts;

        if ( $loop->have_posts() ) {
            while ( $loop->have_posts() ) {
                $loop->the_post();

                $order_id = get_the_ID();
                $order = wc_get_order( $order_id );

                if ( $order ) {
                    $orders_id = $order->get_id();
                    $status = wc_get_order_status_name( $order->get_status() );
                    $date_created = $order->get_date_created()->date( 'd/m/Y' );
                    $payment_method = $order->get_payment_method_title();
                    $order_total = $order->get_formatted_order_total();

                    $items = $order->get_items();
                    foreach ( $items as $item ) {
                        $product_name = $item->get_name();
                        $product_id = $item->get_product_id();
                        $product = wc_get_product( $product_id );
                        if($product){
                            $product_image = $product->get_image();
                        }

                        $view_order = $order->get_view_order_url();
                        $downloads = $order->get_downloadable_items();
                        $download_button = '';

                        if ( is_array( $downloads ) ) {
                            foreach ( $downloads as $product ) {
                                $download_button = '<a href="' . $product[ 'download_url' ] . '" target="_blank">Download</a>';
                            }
                        }

                        $msg .= '
                            <table class="table_orders" border="2">
                                <tr class="table_row_items">
                                  <td class="product_number">
                                   <span class="mobile title">Ordine</span>
                                   <span>#' . esc_attr( $orders_id ) . '</span>
                                  </td>

                                  <td class="product_name">
                                   <span class="mobile title">Prodotto</span>
                                   <a href="' . wp_kses_post( $view_order ) . '">' . wp_kses_post( $product_name ) . '</a>
                                  </td>

                                  <td class="product_data">
                                   <span class="mobile title">Data</span>
                                   <span>' . wp_kses_post( $date_created ) . '</span>
                                  </td>

                                  <td class="product_price">
                                   <span class="mobile title">Prezzo</span>
                                   <span>' . wp_kses_post( $order_total ) . '</span>
                                  </td>

                                  <td class="product_status">
                                   <span class="mobile title">Stato</span>
                                   <span class="label ' . $order->get_status() . '">' . wp_kses_post( $status ) . '</span>
                                  </td>

                                  <td class="product_action">
                                   <span class="mobile title">File</span>
                                   <a target=”_blank” href="' . esc_url( $view_order ) . '">Visualizza<i class="fa-duotone fa-eye"></i></a>
                                  </td>
                                </tr>    
                            </table> 
                        ';
                    }
                }
            }
            wp_reset_postdata();
        }

        $pages_num = intval( ceil( $count / $per_page ) );
        $is_last_page = $pages_num == $paged;
        $is_first_page = $paged === 1;

        $pagination_html = "<div class='pagination-link'>";
        $pagination_html .= "<ul>";

        if ( !$is_first_page ) {
            $pagination_html .= "<li data-pagenum='" . ( $paged - 1 ) . "' class='active'>Previous</li>";
        } else {
            $pagination_html .= "<li class='inactive'>Previous</li>";
        }

        for ( $i = 1; $i <= $pages_num; $i++ ) {
            if ( $paged == $i ) {
                $pagination_html .= "<li data-pagenum='$i' class = 'selected' >{$i}</li>";
            } else {
                $pagination_html .= "<li data-pagenum='$i' class='active'>{$i}</li>";
            }
        }

        if ( !$is_last_page ) {
            $pagination_html .= "<li data-pagenum='" . ( $paged + 1 ) . "' class='active'>Next</li>";
        } else {
            $pagination_html .= "<li class='inactive'>Next</li>";
        }

        $pagination_html .= "</ul>";
        $pagination_html .= "</div>";

        echo '<div class = "pagination-content">' . $msg . '</div>' .
             '<div class = "pagination-nav">' . $pagination_html . '</div>';
    }

    die();
}

前端代码(custom-template.php):

<div class="wrap">
    <div id="primary" class="content-area">
        <div class="col-md-12 content">
            <div class="inner-box content no-right-margin darkviolet">
                <script type="text/javascript">
                    jQuery(document).ready(function ($) {
                        var ajaxurl = '<?php echo admin_url( 'admin-ajax.php' ); ?>';

                        function load_all_posts(page) {
                            var data = {
                                page: page,
                                action: "demo_pagination_posts"
                            };

                            $.post(ajaxurl, data, function (response) {
                                $(".pagination_container").html(response);
                            });
                        }

                        load_all_posts(1);

                        $(document).on('click', '.pagination-link ul li', function () {
                            var page = $(this).attr('data-pagenum');
                            load_all_posts(page);
                        });
                    });
                </script>
                <div class="pag_loading">
                    <div class="pagination_container">
                        <div class="post-content"></div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

5. 注意事项

  • 安全性: 对 $_POST['page'] 进行严格的验证和过滤,防止 SQL 注入攻击。使用 intval() 函数将其转换为整数,并确保其值大于等于 1。
  • 性能: 避免在循环内部执行复杂的数据库查询或计算,以提高性能。
  • 错误处理: 添加适当的错误处理机制,例如检查 wc_get_order() 函数是否返回有效的 WC_Order 对象。
  • 代码重用: 将代码封装成函数或类,以便在其他地方重用。

总结

通过正确设置 WP_Query 参数、使用 the_post() 函数、获取订单详情,并添加适当的错误处理机制,可以解决在使用自定义 WP_Query 获取 WooCommerce 订单详情时遇到的问题。以上提供的代码示例可以作为一个起点,根据实际需求进行修改和扩展。记住要始终关注代码的安全性、性能和可维护性。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

1135

2023.10.12

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

340

2023.10.27

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

381

2024.02.23

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

2255

2024.03.06

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

380

2024.03.06

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

1743

2024.04.07

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

586

2024.04.29

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

441

2024.04.29

C++多线程并发控制与线程安全设计实践
C++多线程并发控制与线程安全设计实践

本专题围绕 C++ 在高性能系统开发中的并发控制技术展开,系统讲解多线程编程模型与线程安全设计方法。内容包括互斥锁、读写锁、条件变量、原子操作以及线程池实现机制,同时结合实际案例分析并发竞争、死锁避免与性能优化策略。通过实践讲解,帮助开发者掌握构建稳定高效并发系统的关键技术。

4

2026.03.16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP课程
PHP课程

共137课时 | 13.7万人学习

JavaScript ES5基础线上课程教学
JavaScript ES5基础线上课程教学

共6课时 | 11.3万人学习

PHP新手语法线上课程教学
PHP新手语法线上课程教学

共13课时 | 1.0万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号