WordPress/WooCommerce中list_products_objects过滤器修改问题求助
解决WordPress/WooCommerce过滤器
list_products_objects的问题 核心错误分析
add_filter参数顺序完全错误
你写的add_filter('remove_product_ids', 'list_products_objects', 10, 2 );把钩子名和回调函数名搞反了,正确顺序是:add_filter( '钩子名', '回调函数名', 优先级, 接收参数数量 )。原插件的钩子名是list_products_objects,必须把这个作为第一个参数。钩子传递的是产品对象数组,不是ID数组
原代码apply_filters('list_products_objects', array_map('wc_get_product', $ids));里,第二个参数是array_map('wc_get_product', $ids)——这是把ID数组转成了WC_Product对象数组,不是你以为的产品ID数组,所以你的回调函数里用$product_ids处理是错误的。分类判断逻辑错误
get_the_terms( $product_id, 'product_cat' )返回的是WP_Term对象数组(或false),直接用in_array和字符串'mugs'对比永远不会成立,因为类型不匹配。函数参数语法错误
function remove_product_ids(array_map('wc_get_product', $product_ids))是非法的PHP语法,函数参数只能是变量或默认值,不能直接写函数调用。
正确的实现代码
// 正确绑定过滤器:钩子名是list_products_objects,回调是remove_product_ids add_filter('list_products_objects', 'remove_product_ids', 10, 1); function remove_product_ids($product_objects) { // 目标分类slug列表 $allowed_cats = array('mugs', 'tshirts'); $filtered_products = array(); // 先确认是数组且不为空 if (!is_array($product_objects) || empty($product_objects)) { return $product_objects; } // 遍历每个产品对象 foreach ($product_objects as $product) { // 确保是WC_Product对象(避免意外错误) if (!$product instanceof WC_Product) { continue; } // 获取当前产品的所有分类slug $product_cat_slugs = wp_get_post_terms( $product->get_id(), 'product_cat', array('fields' => 'slugs') // 直接返回slug数组 ); // 判断产品是否包含目标分类中的任意一个 if (array_intersect($allowed_cats, $product_cat_slugs)) { $filtered_products[] = $product; } } return $filtered_products; }
代码说明
- 过滤器绑定:
add_filter('list_products_objects', 'remove_product_ids', 10, 1)中,最后一个参数1表示回调函数接收1个参数(原钩子只传递了产品对象数组这一个参数)。 - 产品对象校验:用
instanceof WC_Product确保处理的是合法的产品对象,避免报错。 - 分类slug获取:
wp_get_post_terms通过fields => 'slugs'直接获取分类slug数组,省去后续处理对象的步骤。 - 交集判断:
array_intersect检查产品分类slug和目标分类是否有交集,只要有一个匹配就保留该产品。
内容的提问来源于stack exchange,提问作者user22109298
相关产品推荐
相关产品推荐

