PHP表单邮件无法附加上传文件问题排查求助
嘿,我仔细看了你的代码,发现几个关键问题导致附件没法正常发送,咱们一个个来解决:
1. 表单缺少文件上传必需的enctype属性
HTML表单要支持文件上传,必须在<form>标签里加上enctype="multipart/form-data",不然浏览器不会把文件数据提交到服务器,$_FILES数组会是空的。
修改后的表单开头:
<form action="../php/contact-us-main.php" method="POST" enctype="multipart/form-data">
2. 文件字段名不匹配
你的表单里文件输入框的name是attachment,但PHP代码里却用了$_FILES['my_file']——这俩名字必须完全一致!把PHP里的my_file全改成attachment。
修正后的文件变量部分:
$tmp_name = $_FILES['attachment']['tmp_name']; $name = $_FILES['attachment']['name']; $size = $_FILES['attachment']['size']; $type = $_FILES['attachment']['type']; $error = $_FILES['attachment']['error'];
3. 邮件头被错误覆盖
你前面花了功夫构建支持多部分邮件的$headers(包含MIME边界、多部分类型),但后面又重新赋值了$headers = "From: $email_from \r\n";,直接把之前的配置冲没了!这会导致邮件变成纯文本格式,附件根本无法被识别。
要把后面的From和Reply-To追加到之前的headers里,而不是重新赋值:
修正后的headers部分:
// 先定义$email_from,再用在headers里 $email_from = 'xxxxxxxxxxxxxxxxxxxx'; $headers = "MIME-Version: 1.0\r\n"; $headers .= "Reply-To: $first $surname <$email>\r\n"; $headers .= "From: $email_from\r\n"; $headers .= "Content-Type: multipart/mixed; boundary = $boundary\r\n";
4. 邮件主体用错了变量
你构建了包含附件的$body变量,但调用mail()函数时传的是纯文本的$email_body——相当于完全没用到带附件的内容!必须把$body作为邮件主体传进去。
修正后的mail调用:
mail($to, $email_subject, $body, $headers);
5. 未定义的变量导致附件信息错误
你在构建附件部分用了$file_type和$file_name,但这俩变量根本没定义,应该用之前获取的$type和$name,还要记得添加邮件的结束边界:
修正后的附件部分代码:
$body .= "--$boundary\r\n"; $body .= "Content-Type: $type; name=\"$name\"\r\n"; $body .= "Content-Disposition: attachment; filename=\"$name\"\r\n"; $body .= "Content-Transfer-Encoding: base64\r\n"; $body .= "X-Attachment-Id: ".rand(1000, 99999)."\r\n\r\n"; $body .= $encoded_content; // 必须添加结束边界,否则邮件可能解析异常 $body .= "--$boundary--";
完整修正后的PHP代码片段(关键部分)
<?php if($_POST['button'] && isset($_FILES['attachment'])){ $department = $_POST['department']; $title = $_POST['title']; $first = $_POST['first']; $surname = $_POST['surname']; $email = $_POST['email']; $number = $_POST['number']; $userMessage = $_POST['userMessage']; // 修正:使用正确的字段名attachment $tmp_name = $_FILES['attachment']['tmp_name']; $name = $_FILES['attachment']['name']; $size = $_FILES['attachment']['size']; $type = $_FILES['attachment']['type']; $error = $_FILES['attachment']['error']; // 读取文件并编码 $handle = fopen($tmp_name, "r"); $content = fread($handle, $size); fclose($handle); $encoded_content = chunk_split(base64_encode($content)); $boundary = md5("random"); $email_from = 'xxxxxxxxxxxxxxxxxxxx'; // 修正:正确构建headers,不覆盖之前的配置 $headers = "MIME-Version: 1.0\r\n"; $headers .= "Reply-To: $first $surname <$email>\r\n"; $headers .= "From: $email_from\r\n"; $headers .= "Content-Type: multipart/mixed; boundary = $boundary\r\n"; // 构建带附件的邮件主体 $body = "--$boundary\r\n"; $body .= "Content-Type: text/plain; charset=ISO-8859-1\r\n"; $body .= "Content-Transfer-Encoding: base64\r\n\r\n"; // 把文本信息整合到body里 $text_content = "User title: $title. \n". "The department this message is for is: $department.\n". "User First Name: $first.\n". "User Surname Name: $surname. \n". "User email: $email.\n". "User Contact Number: $number.\n". "User Message is: $userMessage.\n"; $body .= chunk_split(base64_encode($text_content)); // 修正:使用正确的变量$type和$name $body .= "--$boundary\r\n"; $body .= "Content-Type: $type; name=\"$name\"\r\n"; $body .= "Content-Disposition: attachment; filename=\"$name\"\r\n"; $body .= "Content-Transfer-Encoding: base64\r\n"; $body .= "X-Attachment-Id: ".rand(1000, 99999)."\r\n\r\n"; $body .= $encoded_content; // 必须添加结束边界 $body .= "--$boundary--"; $email_subject = "New Email Form Submission from $first."; $to = 'xxxxxxxxxxxx'; // 修正:传入正确的$body作为邮件内容 mail($to, $email_subject, $body, $headers); header('Location: https://www.xxxxxxxxxxx.com/pages/thank-you.html'); } ?>
另外,建议加上文件上传的错误检查(比如if($error !== UPLOAD_ERR_OK)时提示用户上传失败),避免文件上传出问题时还继续发送无附件的邮件。
内容的提问来源于stack exchange,提问作者Hunktydunkaty

