Search code examples
phpphpmaileremail-attachments

PhpMailer doesn't send Email with .pdf file attached


I want to send a file via PhpMailer. If the file has extension .txt or .png ecc.. It sends me the email with the file (it works) but if I want to send a .pdf I don't receive the email ... this is a part of my PHP code:

$Name = $_POST['Name'];
$Email = $_POST['Email'];
$Surname = $_POST['Surname'];
$Residence = $_POST['Residence'];
$Phone = $_POST['Phone'];

$Name = filter_var($Name, FILTER_SANITIZE_STRING);
$Surname = filter_var($Surname, FILTER_SANITIZE_STRING);
$Email = filter_var($Email, FILTER_SANITIZE_EMAIL);
$Residence = filter_var($Residence, FILTER_SANITIZE_STRING);;
$Phone = filter_var($Phone, FILTER_SANITIZE_STRING);;

$mail = new PHPMailer();
$mail->SMTPAuth = true;
$mail->Host = "smtp.gmail.com"; // SMTP server
$mail->SMTPSecure = "ssl";
$mail->Username = "xxx"; //account with which you want to send mail. Or use this account. i dont care :-P
$mail->Password = "xxx"; //this account's password.
$mail->SetFrom('xxx');
$mail->Port = "465";
$mail->isSMTP();  // telling the class to use SMTP
$rec1="xxx"; //receiver. email addresses to which u want to send the mail.
$mail->AddAddress($rec1);
$mail->Subject  = "Eventbook";
$mail->isHTML(true);
$mail->Body     = "<h1>Contact from Website</h1>
<ul>
<li>Nome: {$Name}</li>
<li>Cognome: {$Surname}</li>
<li>Comune di residenza: {$Residence}</li>
<li>Email: {$Email}</li>
<li>Telefono: {$Phone}</li>
</ul>";
$mail->WordWrap = 200;
$mail->addAttachment($_FILES['curriculum']['tmp_name'], $_FILES['curriculum']['name']);
if(!$mail->Send()) {
echo 'Message was not sent!.';
$errore = $mail->ErrorInfo;
echo 'Mailer error: ' . $mail->ErrorInfo;
} else {
echo  //Fill in the document.location thing
'<script type="text/javascript">
                        if(confirm("Your mail has been sent"))
                        document.location = "/";
        </script>';
}

This is the JS script with ajax:

var formData = new FormData();
        formData.append('Name', $('#Name').val());
        formData.append('Surname', $('#Surname').val());
        formData.append('Residence', $('#Residence').val());
        formData.append('Email', $('#Email').val());
        formData.append('Phone', $('#Phone').val());
        formData.append('Curriculum', $('#Curriculum')[0].files[0]);
        $.ajax({
            method: 'POST',
            url: "scripts/register.php",
            data: formData,
            processData: false,
            contentType: false,
            success: function (Curriculum) {
                alert('Success');
            }
        });

This is the HTML file input part:

<input type="file" name="Curriculum" id="Curriculum" style="display: none;" class="form__input" />
           <label for="Curriculum" id="LabelCurriculum" class="form__input" style="background-color: white; display: block; width: 100%; padding: 20px; font-family: Roboto; -webkit-appearance: none; border: 0; outline: 0; transition: 0.3s;">Click to upload</label>

It seems that It can't upload due to its size maybe ... because I uploaded .txt and .png of 50KB but the .pdf is 1MB

UPDATE: When I debug I can see that the file is uploaded , so I think that it don't send the email... why????


Solution

  • Don't use values directly from the $_FILES superglobal as they are potentially forgeable. You must validate them using the built-in move_uploaded_file or is_uploaded_file functions. The PHP docs on handling file uploads are excellent, so do what they say.

    Base your code on the send file upload example provided with PHPMailer which uses move_uploaded_file before using the file. It's also a good idea to not use user-supplied filenames so as to avoid the possibility of file overwrite attacks - in the example you'll see it uses a hash of the filename (which will always be safe) to avoid doing that.

    It's a good idea to check return values from critical functions - addAttachment() returns false if it can't read the file you ask it to read, for example:

    if (!$mail->addAttachment($filename, 'file.pdf')) die('Could not read file!');
    

    Look at the file upload size limit set in your PHP config, and mirror that in your form - see here and here. If you exceed this limit, you may find that you still have an entry in your $_FILES array, but it may point to an empty or non-existent file, which is another reason to validate and check return values. You can var_dump($_FILES) to see exactly what your script is receiving - it may not contain what you think it should.

    I can see that you've based your code on a very old example, so make sure you're running the latest version of PHPMailer too.