You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHPMailer支持.doc/图片附件,PDF附件无法发送问题求助

Fix PHPMailer PDF Attachment Sending Failure

Hey there! It looks like you're hitting a snag where PDF attachments won't send through your contact form, even though DOC files and images work perfectly. Let's walk through the most likely issues and how to fix them:

1. First, Capture Detailed Error Messages

Your current code has error reporting commented out, which makes it impossible to pinpoint exactly why PDFs are failing. Start by enabling error logging and PHPMailer's debug output:

error_reporting(E_ALL);
ini_set('display_errors', 1);

Also, after attempting to move the uploaded file, add a quick check to verify the PDF isn't corrupted:

if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
    // Verify the uploaded PDF is intact
    if (!file_exists($uploadfile) || filesize($uploadfile) === 0) {
        echo "Uploaded PDF is corrupted or empty";
        exit;
    }
    // Rest of your PHPMailer code...
}

2. Add Proper File Upload Validation

You're missing critical checks for file type and size, which could let through invalid PDFs (like files over 2MB) or files mislabeled as PDFs. Add this validation before handling the upload:

// Allowed file types (uses real file content MIME types, not client-reported values)
$allowedMimes = [
    'application/pdf',
    'application/msword',
    'image/jpeg',
    'image/png',
    'image/gif'
];
// Allowed file extensions
$allowedExts = ['pdf', 'doc', 'jpg', 'jpeg', 'png', 'gif'];
// 2MB size limit
$maxFileSize = 2 * 1024 * 1024;

$uploadedFile = $_FILES['userfile'];
$fileExtension = strtolower(pathinfo($uploadedFile['name'], PATHINFO_EXTENSION));
$fileMime = mime_content_type($uploadedFile['tmp_name']);

// Check file size
if ($uploadedFile['size'] > $maxFileSize) {
    echo "File exceeds 2MB limit";
    exit;
}
// Double-validate extension and MIME type for security
if (!in_array($fileExtension, $allowedExts) || !in_array($fileMime, $allowedMimes)) {
    echo "Only .doc, .pdf, and image files are allowed";
    exit;
}

Using mime_content_type ensures you're checking the actual file content, not just the filename or client-reported MIME type (which can be faked).

3. Fix PHPMailer's AddAttachment Call

Your current AddAttachment syntax has a small issue—you shouldn't declare the $encoding variable inside the function call. Also, explicitly specifying the PDF's MIME type helps mail clients and servers recognize the attachment correctly:

// Get the actual MIME type of the uploaded file
$attachmentMime = mime_content_type($uploadfile);
// Add the attachment with correct encoding and MIME type
$mail->AddAttachment($uploadfile, $uploadedFile['name'], 'base64', $attachmentMime);

This ensures PHPMailer handles the PDF's encoding properly, which is often the culprit when PDFs fail to send but other files work.

4. Check Server and Gmail SMTP Settings

  • Server Upload Limits: Make sure your PHP config (php.ini) has upload_max_filesize and post_max_size set to at least 2MB (or higher if needed).
  • Gmail SMTP Requirements: If you're using Gmail, ensure:
    • You've enabled "Less secure app access" (if you haven't set up 2FA).
    • If you have 2FA enabled, use an App Password instead of your regular account password.
    • Add SMTP debugging to see exactly what's happening with the connection:
      $mail->SMTPDebug = 2; // Outputs detailed SMTP logs (disable in production)
      $mail->Debugoutput = 'html';
      
      This will show you if Gmail is rejecting the PDF attachment for any reason.

Full Fixed Code Example

<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
date_default_timezone_set('America/Toronto');
require_once('class.phpmailer.php');

$msg = '';
if (array_key_exists('userfile', $_FILES)) {
    // Upload Validation
    $allowedMimes = [
        'application/pdf',
        'application/msword',
        'image/jpeg',
        'image/png',
        'image/gif'
    ];
    $allowedExts = ['pdf', 'doc', 'jpg', 'jpeg', 'png', 'gif'];
    $maxFileSize = 2 * 1024 * 1024;

    $uploadedFile = $_FILES['userfile'];
    $fileExtension = strtolower(pathinfo($uploadedFile['name'], PATHINFO_EXTENSION));
    $fileMime = mime_content_type($uploadedFile['tmp_name']);

    if ($uploadedFile['size'] > $maxFileSize) {
        echo "File exceeds 2MB limit";
        exit;
    }
    if (!in_array($fileExtension, $allowedExts) || !in_array($fileMime, $allowedMimes)) {
        echo "Only .doc, .pdf, and image files are allowed";
        exit;
    }

    // Handle File Upload
    $uploadfile = tempnam(sys_get_temp_dir(), hash('sha256', $uploadedFile['name']));
    if (move_uploaded_file($uploadedFile['tmp_name'], $uploadfile)) {
        if (!file_exists($uploadfile) || filesize($uploadfile) === 0) {
            echo "Uploaded file is corrupted or empty";
            exit;
        }

        // Configure PHPMailer
        $mail = new PHPMailer;
        $mail->IsSMTP();
        $mail->SMTPAuth = true;
        $mail->SMTPSecure = 'tls';
        $mail->Host = "smtp.gmail.com";
        $mail->Port = 587;
        $mail->Username = "exampl@gmail.com";
        $mail->Password = 'your_app_password_or_account_password';
        // Uncomment for debugging:
        // $mail->SMTPDebug = 2;
        // $mail->Debugoutput = 'html';

        $name = $_POST['name'];
        $email = $_POST['email'];
        $message = "Name: ".($name)."\n";
        $message .= "Email: ".($email)."\n";
        $message .= "Message: ".$_POST['message'];

        $mail->addAddress("example@gmail.com");
        $mail->SetFrom($email, $name);
        $mail->Subject = "Message from website";
        $mail->Body = $message;

        // Add Attachment with Correct MIME Type
        $attachmentMime = mime_content_type($uploadfile);
        $mail->AddAttachment($uploadfile, $uploadedFile['name'], 'base64', $attachmentMime);

        if($mail->Send()) {
            echo "Message sent!";
            // Clean up temporary file
            unlink($uploadfile);
        } else {
            echo "Mailer Error: " . $mail->ErrorInfo;
            unlink($uploadfile);
        }
    } else {
        $msg = 'Failed to move file to ' . $uploadfile;
        echo $msg;
    }
}
?>

Final Notes

  • Always delete temporary files after sending the email (the code above uses unlink($uploadfile) to do this) to avoid filling up your server's disk space.
  • Disable error reporting and SMTP debugging when deploying to production to protect sensitive information.
  • If you're still having issues, check the PHPMailer error output—it will tell you exactly where the problem is (e.g., attachment encoding, SMTP authentication, etc.).

内容的提问来源于stack exchange,提问作者webdev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:19:23