WooCommerce 自定义 WP_Query 中获取订单详情时出错的解决方案

聖光之護
发布: 2025-10-08 10:48:11
原创
460人浏览过

woocommerce 自定义 wp_query 中获取订单详情时出错的解决方案

本文旨在解决在使用 WP_Query 在 WooCommerce 中获取订单详情时遇到的常见错误,并提供优化的代码示例。我们将重点关注如何正确获取订单 ID、订单项目,以及如何在 AJAX 调用中实现分页功能,避免常见的 500 错误,并确保数据正确显示。

使用 WP_Query 获取 WooCommerce 订单详情

在使用 WP_Query 查询 WooCommerce 订单时,需要注意几个关键点,以避免常见的错误。首先,要确保正确设置查询参数,特别是 post_type 和 post_status。其次,在循环中正确获取订单 ID 和订单对象。

示例代码:

以下代码展示了如何使用 WP_Query 获取已完成的 WooCommerce 订单,并获取订单 ID 和订单项目:

<?php
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;

    if ( isset( $_POST[ 'page' ] ) ) {
        # 保证页码大于等于 1
        $page = max( 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'          => $page,
        );

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

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

                // 获取订单 ID
                $order_id = $loop->post->ID;

                // 获取订单对象
                $order = wc_get_order( $loop->post->ID );
                $items = $order->get_items();

                $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();

                foreach ( $items as $item ) {
                    $product_name = $item->get_name();
                    $view_order   = $order->get_view_order_url();
                    $product      = $item->get_product();

                    if ( $product instanceof WC_Product ) {
                        $order_img       = $product->get_image();
                        $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> 
                    ';
                    }
                }
            }
        }

        // 分页逻辑
        $pages_num     = intval( ceil( $count / $per_page ) );
        $is_last_page  = $pages_num == $page;
        $is_first_page = $pages_num === 1;

        if ( $page >= 7 ) {
            $start_loop = $page - 3;
            if ( $pages_num > $page + 3 )
                $end_loop = $page + 3;
            else if ( $page <= $pages_num && $page > $pages_num - 6 ) {
                $start_loop = $pages_num - 6;
                $end_loop   = $pages_num;
            } else {
                $end_loop = $pages_num;
            }
        } else {
            $start_loop = 1;
            if ( $pages_num > 7 )
                $end_loop = 7;
            else
                $end_loop = $pages_num;
        }

        $pagination_html = "<div class='pagination-link'>";
        $pagination_html .= "
          <ul>";
            if ( !$is_first_page ) {
                $pagination_html .= "<li data-pagenum='" . ( $page - 1 ) . "' class='active'>Previous</li>";
            } else {
                $pagination_html .= "<li class='inactive'>Previous</li>";
            }
            for ( $i = $start_loop; $i <= $end_loop; $i++ ) {
                if ( $page == $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='" . ( $page + 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();
}
?>
登录后复制

关键点:

百度文心百中
百度文心百中

百度大模型语义搜索体验中心

百度文心百中 22
查看详情 百度文心百中
  • $loop-youjiankuohaophpcnthe_post();: 这个函数设置了全局 $post 变量,允许你使用 get_the_ID() 等函数。
  • $order_id = $loop->post->ID;: 使用 $loop->post->ID 获取订单ID。
  • $order = wc_get_order( $loop->post->ID );: 使用 wc_get_order() 函数获取订单对象。
  • $items = $order->get_items();: 使用 $order->get_items() 获取订单项目。

AJAX 分页

为了实现无需页面刷新的分页功能,需要使用 AJAX。以下代码展示了如何使用 AJAX 调用上述函数,并更新页面内容:

HTML 代码 (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 ($) {
                        // This is required for AJAX to work on our page
                        var ajaxurl = '<?php echo admin_url( 'admin-ajax.php' ); ?>';

                        function load_all_posts(page) {
                            var data = {
                                page: page,
                                action: "demo_pagination_posts"
                            };
                            // Send the data
                            $.post(ajaxurl, data, function (response) {
                                $(".pagination_container").html(response);
                            });
                        }

                        load_all_posts(1); // Load page 1 as the default
                        $(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>
登录后复制

关键点:

  • admin_url( 'admin-ajax.php' ): 获取 WordPress AJAX 处理程序的 URL。
  • $.post(ajaxurl, data, function (response) { ... });: 使用 jQuery 的 $.post() 函数发送 AJAX 请求。
  • $(".pagination_container").html(response);: 使用返回的 HTML 更新页面内容。
  • $(document).on('click', '.pagination-link ul li', function () { ... });: 使用委托事件监听器处理分页链接的点击事件。
  • data-pagenum: 在分页链接上使用 data-pagenum 属性存储页码。

常见问题和注意事项

  • 500 错误: 500 错误通常是由于 PHP 代码中的错误引起的。请检查 functions.php 中的代码,确保没有语法错误或逻辑错误。 启用 WP_DEBUG 可以帮助你找到错误所在。
  • $loop 为 null: 如果 $loop 为 null,可能是由于 WP_Query 的参数设置不正确,导致没有查询到任何结果。请检查 post_type 和 post_status 等参数是否正确。
  • 安全: 始终对用户输入进行消毒和验证,以防止安全漏洞。 使用 sanitize_text_field() 函数对 $_POST['page'] 进行消毒。
  • 性能: 避免在循环中执行数据库查询,这可能会导致性能问题。 尽可能使用 WP_Query 或 wc_get_orders() 函数来批量获取订单数据。
  • get_the_ID() vs $loop->post->ID: 在 WP_Query 循环中,get_the_ID() 和 $loop->post->ID 通常是等价的,但建议使用 $loop->post->ID,因为它更明确地表示你正在访问当前循环中的文章 ID。
  • 分页参数: paged 参数用于指定当前页码。 确保正确计算 offset 值,以便在数据库中跳过正确的记录数。

总结

本文提供了一个完整的解决方案,用于在使用 WP_Query 在 WooCommerce 中获取订单详情时遇到的问题。 通过遵循这些步骤,你可以避免常见的错误,并实现高效、可靠的分页功能。记住,调试是解决问题的关键。 始终检查你的代码,并使用调试工具来查找错误。 通过理解这些概念并应用最佳实践,你可以构建强大的 WooCommerce 解决方案,满足你的业务需求。

以上就是WooCommerce 自定义 WP_Query 中获取订单详情时出错的解决方案的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

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