Mihail Ivanchev Mihail Ivanchev - 1 month ago 22
PHP Question

How to send multiple attachments to email

I have the following simple form that is ment to send multiple files to email:

<form method="post" enctype="multipart/form-data">
<input id="upload-file" class="upload-file" type="file" name="my_file[]" multiple>
<input type="submit" value="Send">
</form>


I am using the following php code to do the actual sending:

if (isset($_FILES['my_file'])) {
$to = 'my-email@maybe-gmail.com';
$subject = 'Files moar files';
$message = 'Message Body';
$headers = 'Some random email header';
$attachments = array();
$myFile = $_FILES['my_file'];
$fileCount = count($myFile["name"]);
for ($i = 0; $i < $fileCount; $i++) {

$attachments[$i] = $_FILES['my_file']['tmp_name'][$i];
}
wp_mail($to, $subject, $message, $headers, $attachments);
}


I am using wp_mail() method, because this is in a Wordpress website(it is the same as the php mail() function).
My problem is, that I receive an email with the attachments, but the name of the file is messed up, and there is no extension, so it's hard to open it. What am I doing wrong here, and how can I fix it?

Answer

When you upload files in PHP, they are uploaded to a temporary directory and given a random name. This is what is stored in the 'tmp_name' key for each of the files. It also explains why each file does not have an extension when sent via email, as they are simply stored as files in the temporary directory. The original file name is stored in the 'name' key.

The easiest way to deal with this issue is to rename the files to their appropriate file names and then send them, because it doesn't seem that WordPress supports a second field to provide the file name for each file.

$uploaddir = '/var/www/uploads/'; //Or some other temporary location
$myFile = $_FILES['my_file'];
$fileCount = count($myFile["name"]);
for ($i = 0; $i < $fileCount; $i++) {
    $uploadfile = $uploaddir . basename($_FILES['my_file']['name'][$i]);
    if (!move_uploaded_file($_FILES['my_file']['tmp_name'][$i], $uploadfile)) {
        //If there is a potential file attack, stop processing files.
        break;
    }
    $attachments[$i] = $uploadfile;

}
wp_mail($to, $subject, $message, $headers, $attachments);

//clean up your temp files after sending
foreach($attachments as $att) {
    @unlink($att);
}

When dealing with files it's also a good practice to validate MIME types and restrict the types of files that you support.

WordPress wp_mail: https://developer.wordpress.org/reference/functions/wp_mail/ PHP POST Uploads: http://php.net/manual/en/features.file-upload.post-method.php

Comments