如何从动态生成的WordPress表单中获取字段值并通过PHP发邮件
解决动态表单提交后获取字段标签和值并发送邮件的问题
看起来你现在的核心问题是动态生成的表单字段用了数组式的name(如text[]、email[]),没法把提交的值和对应的字段标签关联起来,而且现有代码里硬编码了field1、field3这种固定字段名,完全不匹配动态表单的结构。我来一步步帮你修正:
第一步:调整数据库存储(关键前提)
首先,你当前的contactform表只存了拼接好的form_content HTML,这导致后端没法知道每个输入框对应的标签。所以需要添加一个字段来存储每个表单的字段配置信息(标签、类型):
- 给
wp_contactform表添加form_fields字段(类型为TEXT即可),用来序列化存储字段数组。 - 当你用表单生成器创建表单时,除了生成
form_contentHTML,还要把每个字段的标签、类型整理成数组,序列化后存入form_fields。例如生成表单的代码大概是这样:
// 示例:假设这是你表单生成器里的字段配置 $fields = [ ['label' => '姓名', 'type' => 'text'], ['label' => '邮箱', 'type' => 'email'], ['label' => '主题', 'type' => 'text'], ['label' => '留言内容', 'type' => 'text'], ]; // 生成表单HTML $form_content = ''; foreach($fields as $field) { $form_content .= '<div class="form-group">'; $form_content .= '<label class="control-label">'.$field['label'].'</label>'; $form_content .= '<input type="'.$field['type'].'" name="'.$field['type'].'[]" class="form-control">'; $form_content .= '</div>'; } // 存储到数据库(包含序列化的字段配置) global $wpdb; $wpdb->insert( $wpdb->prefix . 'contactform', [ 'form_name' => '联系表单', 'email' => 'your-admin@example.com', 'subject' => '新的表单提交', 'sender' => '你的网站', 'form_content' => $form_content, 'form_fields' => serialize($fields), // 关键:存储字段配置 ] );
第二步:修改短代码函数,处理表单提交
接下来,更新你的shortcode_form函数,让它能正确解析数组式的表单字段,并关联标签:
function shortcode_form(){ global $wpdb; $table_name = $wpdb->prefix . 'contactform'; $query = $wpdb->get_results("SELECT * FROM $table_name"); // 假设你只有一条表单记录,取第一条即可(如果有多条,需要根据短代码参数筛选) $info = $query[0]; $form_name = $info->form_name; $email = $info->email; $subject = $info->subject; $sender = $info->sender; $form_content = $info->form_content; $form_fields = unserialize($info->form_fields); // 反序列化字段配置 $content = ''; // 处理表单提交 if ( isset( $_POST['submit'] ) ) { // 清理提交的数组值 $text_values = isset($_POST['text']) ? array_map('sanitize_text_field', $_POST['text']) : []; $email_values = isset($_POST['email']) ? array_map('sanitize_email', $_POST['email']) : []; // 构造邮件内容:关联标签和对应的值 $body = "你收到了一条新的表单提交:\n\n"; $text_idx = 0; $email_idx = 0; foreach($form_fields as $field){ $label = sanitize_text_field($field['label']); switch($field['type']){ case 'text': if(isset($text_values[$text_idx])){ $body .= "*{$label}:* {$text_values[$text_idx]}\n\n"; $text_idx++; } break; case 'email': if(isset($email_values[$email_idx])){ $body .= "*{$label}:* {$email_values[$email_idx]}\n\n"; $email_idx++; } break; } } // 邮件配置 $to = sanitize_email($email); $mail_subject = sanitize_text_field($subject); // 用第一个邮箱字段作为回复邮箱(如果有的话) $reply_to = !empty($email_values) ? $email_values[0] : $to; $headers = 'From: ' . sanitize_text_field($sender) . ' <' . $to . '>' . "\r\n" . 'Reply-To: ' . $reply_to; // 发送邮件并反馈结果 if(wp_mail($to, $mail_subject, $body, $headers)){ $content .= '<div class="alert alert-success">表单提交成功,我们会尽快回复你!</div>'; } else { $content .= '<div class="alert alert-danger">提交失败,请稍后重试或联系管理员。</div>'; } } // 拼接表单HTML(记得添加提交按钮,否则$_POST['submit']不会触发) $content.= '<form method="POST" action="" class="form-horizontal">'; $content.= $form_content; $content.= '<button type="submit" name="submit" class="btn btn-primary mt-3">提交表单</button>'; $content.= '</form>'; return $content; } add_shortcode('dynamic_contact_form', 'shortcode_form');
关键说明
- 数组字段的处理:用
array_map批量清理text[]和email[]数组的每个值,确保安全。 - 标签与值的关联:通过反序列化存储的
form_fields数组,我们能准确知道每个text[]/email[]元素对应的标签,避免硬编码。 - 邮件发送的细节:修复了你原代码里未定义的
$get_mailinfo变量,改用从数据库取出的真实配置;同时添加了提交结果的反馈提示,提升用户体验。 - 提交按钮:必须添加
name="submit"的提交按钮,否则isset($_POST['submit'])不会检测到提交动作。
如果你的表单生成器没法直接修改存储逻辑,也可以考虑在生成form_content时,给每个输入框添加data-label属性,然后通过前端JS把标签和值一起提交,但这种方式不如后端存储字段配置可靠。
内容的提问来源于stack exchange,提问作者Djouonang
相关产品推荐
相关产品推荐

