
本文介绍两种兼容现代 WooCommerce 版本的方法:一是利用 wc_get_product_id_by_sku() 替换默认商品 ID 解析逻辑,实现 URL 参数(如 ?add-to-cart=123)中传入 SKU 自动识别;二是通过自定义查询参数 ?add-to-cart-sku=ABC123 精准触发加购,支持任意字符 SKU,兼顾安全性与扩展性。
本文介绍两种兼容现代 woocommerce 版本的方法:一是利用 `wc_get_product_id_by_sku()` 替换默认商品 id 解析逻辑,实现 url 参数(如 `?add-to-cart=123`)中传入 sku 自动识别;二是通过自定义查询参数 `?add-to-cart-sku=abc123` 精准触发加购,支持任意字符 sku,兼顾安全性与扩展性。
在多系统集成场景下(例如同一商品需同步至 WordPress/WooCommerce 与其他 CMS),依赖 WooCommerce 自动生成的 product_id 会导致跨平台 ID 不一致。此时,使用商品 SKU 作为唯一标识符是更可靠的选择。WooCommerce 自 3.0+ 版本起已内置 wc_get_product_id_by_sku() 函数,它不仅性能更优、自动排除回收站商品,还天然支持含字母、连字符、下划线等任意合法 SKU 字符串(如 PRO-2024-DELUXE),彻底替代了原始 SQL 查询方案。
✅ 推荐方案一:透明兼容原生 add-to-cart 参数(适用于简单场景)
该方案保持原有链接结构(如 /shop/?add-to-cart=SKU123),仅通过钩子拦截并解析 SKU,对前端无侵入性:
function filter_woocommerce_add_to_cart_product_id( $product_id ) {
// 若传入值已是有效 product ID(即 post_type == 'product'),直接返回
if ( get_post_type( $product_id ) === 'product' ) {
return $product_id;
}
// 否则视为 SKU,尝试查找对应 product ID
$found_id = wc_get_product_id_by_sku( $product_id );
return $found_id ? $found_id : $product_id; // 未找到则保留原值,交由后续逻辑处理
}
add_filter( 'woocommerce_add_to_cart_product_id', 'filter_woocommerce_add_to_cart_product_id', 10, 1 );
⚠️ 注意:此方式要求前端链接中 add-to-cart 参数值必须为 SKU 字符串(而非数字 ID),例如:
https://yoursite.com/shop/?add-to-cart=WOODEN-DESK-001
若同时存在 ID 和 SKU 混用,建议配合前端校验或统一约定。
✅ 推荐方案二:专用参数 add-to-cart-sku(推荐用于生产环境)
为避免与原生 ID 逻辑冲突,并提升可维护性与安全性,建议采用独立查询参数 add-to-cart-sku。以下代码完整复现 WooCommerce 原生加购流程,支持简单商品、变体、组合商品等全部类型:
function handle_add_to_cart_by_sku() {
// 前置校验:确保 WooCommerce 已加载,且参数存在且为字符串
if ( ! class_exists( 'WC_Form_Handler' )
|| ! isset( $_REQUEST['add-to-cart-sku'] )
|| ! is_string( $_REQUEST['add-to-cart-sku'] ) ) {
return;
}
// 移除 WooCommerce 默认加购钩子,防止重复执行
remove_action( 'wp_loaded', array( 'WC_Form_Handler', 'add_to_cart_action' ), 20 );
wc_nocache_headers(); // 防止缓存导致加购失败
$sku = wp_unslash( $_REQUEST['add-to-cart-sku'] );
$product_id = wc_get_product_id_by_sku( $sku );
$product = wc_get_product( $product_id );
if ( ! $product ) {
wc_add_notice( sprintf( __( 'Product with SKU "%s" not found.', 'textdomain' ), esc_html( $sku ) ), 'error' );
return;
}
// 复用 WC_Form_Handler 的私有加购逻辑(通过反射调用)
$add_to_cart_handler = apply_filters( 'woocommerce_add_to_cart_handler', $product->get_type(), $product );
$was_added = false;
switch ( $add_to_cart_handler ) {
case 'variable':
case 'variation':
$was_added = invoke_wc_form_handler_method( 'add_to_cart_handler_variable', $product_id );
break;
case 'grouped':
$was_added = invoke_wc_form_handler_method( 'add_to_cart_handler_grouped', $product_id );
break;
default:
if ( has_action( "woocommerce_add_to_cart_handler_{$add_to_cart_handler}" ) ) {
do_action( "woocommerce_add_to_cart_handler_{$add_to_cart_handler}", '' );
} else {
$was_added = invoke_wc_form_handler_method( 'add_to_cart_handler_simple', $product_id );
}
break;
}
// 成功后重定向(遵循 WooCommerce 设置)
if ( $was_added && 0 === wc_notice_count( 'error' ) ) {
$redirect_url = apply_filters( 'woocommerce_add_to_cart_redirect', '', $product );
if ( $redirect_url ) {
wp_safe_redirect( $redirect_url );
} elseif ( 'yes' === get_option( 'woocommerce_cart_redirect_after_add' ) ) {
wp_safe_redirect( wc_get_cart_url() );
}
exit;
}
}
add_action( 'wp_loaded', 'handle_add_to_cart_by_sku', 15 );
// 辅助函数:安全调用 WC_Form_Handler 私有方法
function invoke_wc_form_handler_method( $method_name, $product_id ) {
if ( version_compare( phpversion(), '5.3', 'getMethod( $method_name );
$method->setAccessible( true );
return $method->invoke( null, $product_id );
}
? 使用示例与注意事项
前端调用方式:
Add ABC-2024-XL to Cart-
安全性说明:
- 使用 wp_unslash() 和 wc_get_product_id_by_sku() 内置校验,自动过滤无效/不存在 SKU;
- wp_safe_redirect() 确保跳转 URL 经过白名单验证;
- 错误时通过 wc_add_notice() 提供用户友好提示。
扩展建议:
可进一步结合 woocommerce_add_to_cart_redirect 过滤器,实现 SKU 加购后跳转至专属落地页;或添加数量参数(如 &quantity=2)支持批量添加。
通过以上任一方案,即可彻底摆脱对 product_id 的硬依赖,在多 CMS 协同、ERP 对接、API 集成等场景中实现稳定、可移植的商品加购能力。











