WooCommerce获取指定product_tag商品时$item仅返回最后一项问题
WooCommerce 按商品标签输出购物车匹配商品列表变量只返回最后一项修复
问题场景
需求为展示带有指定product_tag的WooCommerce商品列表,原有实现代码如下:
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) { $_product = apply_filters( 'woocommerce_cart_item_product', $cart_item['data'], $cart_item, $cart_item_key ); if ( $_product && $_product->exists() && has_term( 'no-expedite', 'product_tag', $cart_item['product_id'] ) && apply_filters( 'woocommerce_checkout_cart_item_visible', true, $cart_item, $cart_item_key ) ) { $cat_in_cart = true; ob_start(); echo '<ul> <li>'. wp_kses_post( apply_filters( 'woocommerce_cart_item_name', $_product->get_name(), $cart_item, $cart_item_key ) ) . '</li></ul>'; $item = ob_get_clean(); } //break; } // IF Tag is in cart or expedite disabled is True if ( $cat_in_cart || $expedite_disabled ) { $fields['billing']['noneexpediteableitems']['subtitle']='The following items can not be expedited:' . '<br>' . $item . '<br>' . 'If you would like expedite the items not listed above, please remove the none expediteable items and order them seperatly.'; }
该代码直接echo输出时可以正常展示所有符合标签条件的商品,但将输出捕获存入$item变量后,变量仅返回列表最后一项,无法获取完整商品列表。当前站点使用Themehigh Checkout Field Editor自定义结账流程。
故障原因
循环匹配到符合条件的商品时,每次都会重新执行ob_start()开启新的输出缓冲,再通过ob_get_clean()获取当前缓冲内容的同时清空缓冲,直接对$item变量做覆盖赋值。循环结束后$item只会保留最后一次匹配到的商品内容。
另外原有逻辑每次循环都输出完整的<ul>标签包裹单个<li>,生成的HTML结构也不符合规范。
修复代码
推荐直接使用字符串拼接实现,不需要依赖输出缓冲,性能更好,同时修正HTML结构问题:
// 提前初始化变量,避免未定义变量报错 $cat_in_cart = false; $item = ''; foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) { $_product = apply_filters( 'woocommerce_cart_item_product', $cart_item['data'], $cart_item, $cart_item_key ); if ( $_product && $_product->exists() && has_term( 'no-expedite', 'product_tag', $cart_item['product_id'] ) && apply_filters( 'woocommerce_checkout_cart_item_visible', true, $cart_item, $cart_item_key ) ) { $cat_in_cart = true; // 拼接商品项,不要覆盖原有变量内容 $item .= '<li>'. wp_kses_post( apply_filters( 'woocommerce_cart_item_name', $_product->get_name(), $cart_item, $cart_item_key ) ) . '</li>'; } } // 所有商品遍历完成后,统一添加外层ul标签 if ( $cat_in_cart ) { $item = '<ul>' . $item . '</ul>'; } // 存在不可加急商品或全局加急功能禁用时,输出提示 if ( $cat_in_cart || $expedite_disabled ) { $fields['billing']['noneexpediteableitems']['subtitle'] = 'The following items can not be expedited:<br>' . $item . '<br>If you would like expedite the items not listed above, please remove the none expediteable items and order them seperatly.'; }
如果需要使用输出缓冲实现,只需将ob_start()放到循环外部,遍历完成后再统一获取缓冲内容即可,不要在循环内反复开关缓冲。
内容的提问来源于stack exchange,提问作者OCI-Jacobcr
相关产品推荐
相关产品推荐

