
本文详解如何在 WooCommerce 用户注册表单中,为自定义文本字段(如邀请码/密钥)添加严格校验逻辑:仅当输入值精确匹配数据库 secret_codes 表中的某条 code 记录时才允许注册成功,否则中断提交并显示友好错误提示。
本文详解如何在 woocommerce 用户注册表单中,为自定义文本字段(如邀请码/密钥)添加严格校验逻辑:仅当输入值精确匹配数据库 `secret_codes` 表中的某条 `code` 记录时才允许注册成功,否则中断提交并显示友好错误提示。
在 WooCommerce 中扩展注册流程时,常需对用户输入的自定义字段(例如“激活码”“推荐码”或“内部密钥”)进行强一致性验证——不能仅检查非空或格式,而必须确保该值真实存在于 wordpress 数据库的指定表中(如 wp_secret_codes)。这属于典型的业务约束型校验,需在用户提交瞬间完成数据库查询与比对,并阻止非法注册。
✅ 正确实现步骤
1. 在注册表单中添加自定义字段(前端)
首先确保你的自定义字段已正确输出在注册页(通常通过 woocommerce_register_form 钩子):
// functions.php 或插件文件中 add_action('woocommerce_register_form', 'add_registration_code_field'); function add_registration_code_field() { woocommerce_form_field('registration_code', array( 'type' => 'text', 'required' => true, 'label_class' => array('woocommerce-form__label'), 'input_class' => array('woocommerce-Input woocommerce-Input--text input-text'), 'label' => __('邀请码(必填)', 'woocommerce'), 'placeholder' => __('请输入有效的邀请码', 'woocommerce') )); }
2. 执行服务端校验(关键:woocommerce_register_post)
使用 woocommerce_register_post 钩子拦截提交,在创建用户前完成数据库校验。注意:必须使用 $wpdb->get_var() 或 $wpdb->get_row() 获取实际数据,而非 $wpdb->query()(它返回影响行数,无法判断是否存在匹配记录)。
add_action('woocommerce_register_post', 'validate_registration_code', 10, 3); function validate_registration_code($username, $email, $validation_errors) { global $wpdb; $input_code = isset($_POST['registration_code']) ? sanitize_text_field(wp_unslash($_POST['registration_code'])) : ''; if (empty($input_code)) { $validation_errors->add('registration_code_error', __('<strong>错误</strong>:邀请码不能为空。', 'woocommerce')); return; } // 假设表名为 wp_secret_codes,字段为 code(请按实际表结构调整) $table_name = $wpdb->prefix . 'secret_codes'; $valid_code = $wpdb->get_var($wpdb->prepare( "SELECT code FROM {$table_name} WHERE code = %s LIMIT 1", $input_code )); if (!$valid_code) { $validation_errors->add( 'registration_code_error', __('<strong>错误</strong>:您输入的邀请码无效,请确认后重试。', 'woocommerce') ); } }
⚠️ 重要注意事项:
3. (可选)注册成功后消耗/标记该码
若邀请码为一次性使用,可在用户创建后更新数据库(例如添加 used_at 时间戳或删除记录),通过 woocommerce_created_customer 钩子实现:
add_action('woocommerce_created_customer', 'mark_code_as_used'); function mark_code_as_used($customer_id) { global $wpdb; $input_code = isset($_POST['registration_code']) ? sanitize_text_field(wp_unslash($_POST['registration_code'])) : ''; if (empty($input_code)) return; $table_name = $wpdb->prefix . 'secret_codes'; $wpdb->update( $table_name, ['used_at' => current_time('mysql')], ['code' => $input_code], ['%s'], ['%s'] ); }
✅ 总结
- 校验必须在 woocommerce_register_post 阶段完成,早于用户写入数据库;
- 使用 $wpdb->get_var() 判断值是否存在,语义清晰且高效;
- 前端字段名(如 ‘registration_code’)需与 $_POST 键名完全一致;
- 始终对用户输入执行 sanitize_text_field() + $wpdb->prepare() 双重防护;
- 错误信息应明确、友好,避免暴露数据库结构等敏感信息。
通过以上方式,你将构建出一个安全、可靠且符合业务规则的注册码校验机制,真正实现“仅白名单可注册”的管控目标。