I
I
Irina Kondratyuk2016-02-01 12:10:43
PHP
Irina Kondratyuk, 2016-02-01 12:10:43

PHP send multiple files to email. Wrong cycle?

Good people, php gurus help the girl. I fight the 4th day over a problem. There is a samopisnaya form, from the form all the data is sent to the soap. Everything is fine, but I ran into a problem, when attaching several files, only one comes to the mail, I made a cycle, mail is outside the cycle, one file still comes, if I transfer the mail function itself to the cycle, then when sending, for example, 4 files, it comes 4 letters and each letter has a separate file, how to put it all together. Due to the while ($i <= 3) check, emails only arrive when there are 3 or more attachments. I think you need to somehow insert a variable instead of a number, which will store the number of attached files.
Well, the main question is how to add all attached files to $multipart so that they come in one letter.
I moved the form to a separate file, cut out everything superfluous, checks, etc., so that there was not a bunch of code.
Link to form
Thank you in advance.

<input class="upload-link__inp" name="mail_file[]" type="file" multiple/>

function sendMail($mailTo, $title, $html, $file)
    {
        
        if (empty($file)) { // если файла нет, то отправляем обычно письмо
            $headers = "From: Robot\r\n";
            $headers .= "MIME-Version: 1.0;\r\n";
            $headers .= "Content-type: text/html; charset=UTF-8\r\n";
            mail($mailTo, $title, $html, $headers);
        } else {  // если есть вложение к почте, то изобретаем велосипед :)
            
            $i = 0;
            while ($i <= 3){
            
            $fp = fopen($file["tmp_name"][$i], "rb");
            if (!$fp) {
                echo "Cannot open file";
                exit();
            }
            $data = fread($fp, filesize($file["tmp_name"][$i]));
            fclose($fp);
            
            $name = $file["name"][$i];
            
            $boundary = "--" . md5(uniqid(time()));

            $headers = "MIME-Version: 1.0;\r\n";
            $headers .= "From: Robot\r\n";
            $headers .= "Content-Type: multipart/mixed; boundary=\"$boundary\"\r\n";
                 
            $multipart = "--$boundary\r\n";
            $multipart .= "Content-Type: text/html; charset=UTF-8\r\n";
            $multipart .= "Content-Transfer-Encoding: base64\r\n";
            $multipart .= "\r\n";
            $multipart .= chunk_split(base64_encode($html));

            $multipart .= "\r\n\r\n--$boundary\r\n";
            $multipart .= "Content-Type: " . $file["type"][$i] . "; name=\"$name\"\r\n";
            $multipart .= "Content-Transfer-Encoding: base64 \r\n";
            $multipart .= "Content-Disposition: attachment; filename=\"$name\"\r\n";
            $multipart .= "\r\n";
            $multipart .= chunk_split(base64_encode($data));
            $multipart .= "\r\n--$boundary--\r\n";
      
                $i++;
                
            }
            mail($mailTo, $title, $multipart, $headers);
        }

    }
    
        if (!empty($_FILES["mail_file"])) {
                    $file = array();
                    $file = $_FILES["mail_file"];
        }

   sendMail($mailTo, $title, $html, $file);

Answer the question

In order to leave comments, you need to log in

2 answer(s)
V
Vladimir Dubrovin, 2016-02-01
@7unikum

You change the boundary in the loop, and it should be the same between all parts. There should also be only one HTML part. To fix this part

$boundary = "--" . md5(uniqid(time()));

            $headers = "MIME-Version: 1.0;\r\n";
            $headers .= "From: Robot\r\n";
            $headers .= "Content-Type: multipart/mixed; boundary=\"$boundary\"\r\n";
                 
            $multipart = "--$boundary\r\n";
            $multipart .= "Content-Type: text/html; charset=UTF-8\r\n";
            $multipart .= "Content-Transfer-Encoding: base64\r\n";
            $multipart .= "\r\n";
            $multipart .= chunk_split(base64_encode($html));

it is necessary to raise it higher, leave it inside the else but take it out of the file loop, because it should only be run once.

A
Andrey Mokhov, 2016-02-01
@mokhovcom

uniqid is not exactly unique
such code will give the following output

for ($i=0; $i<10; $i++) {
  echo uniqid(''), PHP_EOL;
}

result
56af220bd338b
56af220bd338b
56af220bd338b
56af220bd338b
56af220bd3773
56af220bd3773
56af220bd3773
56af220bd3773
56af220bd3773
56af220bd3773

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question