如何为现有PHP邮件表单添加附件功能并限制文件大小?
实现邮件表单带附件发送(5MB大小限制)
先修正你的HTML表单——原代码里嵌套了<form>标签,这会导致上传失效,而且文件上传必须加enctype="multipart/form-data"才能正确传递文件。修改后的HTML如下:
<form id="booking-form" class="booking-form" name="form1" method="post" action="" enctype="multipart/form-data"> <div align="center"><img class="logo" src="img/example_logo.png" title="Example Logo" alt="Example Logo"></div> <div class="h1"><strong>Kontaktieren Sie uns</strong></div> <div id="form-message" class="message hide"> Vielen Dank für Ihre Anfrage, wir werden uns so schnell wie möglich bei Ihnen melden, um Ihre Anfrage zu bearbeiten<br><a class="" href="../index.html">zurück zur Homepage</a> </div> <div id="form-content"> <div class="group"> <label for="name">Name:</label> <div><input id="name" name="name" class="form-control" type="text" placeholder=""></div> </div> <div class="group"> <label for="email">Email:</label> <div><input id="email" name="email" class="form-control" type="email" placeholder=""></div> </div> <div class="group"> <label for="phone">Telefon:</label> <div><input id="phone" name="phone" class="form-control" type="number" placeholder=""></div> </div> <div class="group"> <label for="special-requirements">Nachricht:</label> <div><textarea id="special-requirements" name="special-requirements" class="form-control" cols="" rows="5" placeholder=""></textarea></div> </div> <div class="group"> <label for="myFile">附件:</label> <div><input type="file" id="myFile" name="filename"></div> </div> <div class="group"> <input type="radio" name="AGB" value="OK" checked>Hiermit akzeptiere ich die <a href="../DSGVO.html">DSGVO</a> </div> <div class="group submit"> <label class="empty"></label> <div><input name="submit" type="submit" value="Absenden"/></div> </div> </div> <div id="form-loading" class="hide"><i class="fa fa-circle-o-notch fa-spin"></i></div> </form>
HTML修改要点:
- 删除了嵌套的多余
<form>标签 - 主表单添加
enctype="multipart/form-data"属性(文件上传必备) - 给文件按钮补充了标签,优化界面可读性
接下来修改PHP脚本,实现文件大小限制和带附件的邮件发送:
<?php define('_EMAIL_TO', 'xxx@xxx.xx'); // 收件邮箱地址 define('_EMAIL_SUBJECT', 'XXX'); // 邮件主题 define('_MAX_FILE_SIZE', 5 * 1024 * 1024); // 5MB大小限制,单位字节 $error_fields = array(); $email_content = array(); // 表单字段验证逻辑 $fields = array( array('name' => 'AGB', 'title' => 'AGB '), array('name' => 'name', 'title' => 'Name', 'valid' => array('require')), array('name' => 'phone', 'title' => 'Telefon', 'valid' => array('require')), array('name' => 'email', 'title' => 'Email', 'valid' => array('require', 'email')), array('name' => 'special-requirements', 'title' => 'Nachricht') ); foreach ($fields AS $field){ $value = isset($_POST[$field['name']])?$_POST[$field['name']]:''; $title = empty($field['title'])?$field['name']:$field['title']; $email_content[] = $title.': '.nl2br(stripslashes($value)); $is_valid = true; $err_message = ''; if (!empty($field['valid'])){ foreach ($field['valid'] AS $valid) { switch ($valid) { case 'require': $is_valid = $is_valid && strlen($value) > 0; $err_message = '此字段为必填项'; break; case 'email': $is_valid = $is_valid && preg_match("/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$/i", $value); $err_message = '请输入有效的邮箱地址'; break; default: break; } } } if (!$is_valid){ if (!empty($field['err_message'])){ $err_message = $field['err_message']; } $error_fields[] = array('name' => $field['name'], 'message' => $err_message); } } // 处理文件上传验证 $attachment = null; if (!empty($_FILES['filename']['name'])) { // 检查文件大小是否超标 if ($_FILES['filename']['size'] > _MAX_FILE_SIZE) { $error_fields[] = array('name' => 'filename', 'message' => '附件大小不能超过5MB'); } // 检查上传是否出错 if ($_FILES['filename']['error'] !== UPLOAD_ERR_OK) { $error_fields[] = array('name' => 'filename', 'message' => '文件上传失败,请重试'); } // 读取文件内容(验证通过后) if (empty($error_fields)) { $attachment = array( 'name' => $_FILES['filename']['name'], 'type' => $_FILES['filename']['type'], 'content' => file_get_contents($_FILES['filename']['tmp_name']) ); } } // 发送邮件 if (empty($error_fields)) { $from_email = $_POST['email']; $boundary = uniqid('np'); // 生成唯一的邮件内容分隔符 // 构建邮件头部 $headers = "MIME-Version: 1.0\r\n"; $headers .= "From: $from_email\r\n"; $headers .= "Reply-To: $from_email\r\n"; $headers .= "Content-Type: multipart/mixed; boundary=" . $boundary . "\r\n"; // 邮件正文内容 $message = "--" . $boundary . "\r\n"; $message .= "Content-Type: text/html; charset=utf-8\r\n"; $message .= "Content-Transfer-Encoding: 8bit\r\n\r\n"; $message .= implode('<hr>', $email_content) . "\r\n\r\n"; // 添加附件(如果有) if ($attachment) { $message .= "--" . $boundary . "\r\n"; $message .= "Content-Type: " . $attachment['type'] . "; name=\"" . $attachment['name'] . "\"\r\n"; $message .= "Content-Transfer-Encoding: base64\r\n"; $message .= "Content-Disposition: attachment; filename=\"" . $attachment['name'] . "\"\r\n\r\n"; $message .= chunk_split(base64_encode($attachment['content'])) . "\r\n"; } // 结束分隔符 $message .= "--" . $boundary . "--"; // 发送邮件并返回结果 if (mail(_EMAIL_TO, _EMAIL_SUBJECT, $message, $headers)) { echo json_encode(array('code' => 'success')); } else { $error_fields[] = array('name' => 'system', 'message' => '邮件发送失败,请稍后重试'); echo json_encode(array('code' => 'failed', 'fields' => $error_fields)); } } else { echo json_encode(array('code' => 'failed', 'fields' => $error_fields)); } ?>
PHP修改要点:
- 新增
_MAX_FILE_SIZE常量,明确设置5MB的文件大小限制 - 加入文件上传验证逻辑:检查文件大小、上传错误状态
- 重构邮件结构,使用
multipart/mixedMIME类型实现附件支持 - 将附件内容转成Base64编码,符合邮件传输规范
- 完善错误处理,新增邮件发送失败的反馈
额外提醒:
- 确保PHP配置中的
upload_max_filesize和post_max_size参数值不小于5MB(可在php.ini中修改,或用ini_set()临时调整) - 如果需要限制文件类型,可以在文件验证部分添加扩展名或MIME类型检查
- 上传的临时文件会在脚本执行完毕后自动删除,无需手动清理
内容的提问来源于stack exchange,提问作者Johannes Pohle
相关产品推荐
相关产品推荐

