PHP表单文件上传:2个输入,但只附加1个文件

时间:2014-10-08 14:30:25

标签: php arrays forms file foreach

我试图想出这个问题一段时间,但似乎无法得到它。我有一个工作代码,一个文件上传工作正常,现在尝试创建一个2上传。为了尝试添加多个文件,我添加了一个foreach循环,并将表单输入的name属性切换为name =“photo []”,以便它读取一个数组。表单提交没有错误,但我仍然只收到电子邮件附件中的第一个文件。我见过很多类似的问题,但仍然无法得到它 - 谢谢你的耐心等待! (我也玩过:

for($i = 0; $i < 2; $i++) {

代替和foreach)但这是我现在的代码。

HTML表格:

<form enctype="multipart/form-data" method= "post" action="couple_uploader_test.php"> 
   <input type="hidden" name="myEmail" value="info@website.co.uk"> 
   <input type="hidden" name="subject" value="Couple Portrait Order">
   <label>Name:</label><input type="text" name="customerName" required="true"/><br/>
   <label>Email:</label><input type="email" name="customerEmail" required="true"/><br/>
   <label>Photo:</label><input type="file" name="photo[]" accept="image/*" required="true"/>
   <label>2nd Photo (optional):</label><input type="file" name="photo[]" accept="image/*"/>
   <label>Notes:</label><textarea name="message" cols="30" rows="6">customer message here</textarea>
   <input type="hidden" name="thankyou_url" value="http://www.website.co.uk/html/couple_uploaded.html"/>
   <input type="submit" value="Submit Photo"/>
</form>

上传者PHP:

<?php
$to = $_POST['myEmail'];
$from = $_POST['customerEmail'];
$name = $_POST['customerName'];
$subject = $_POST['subject'];
$message = $_POST['message']."\n\n" . $name;

$message = wordwrap($message,70);

foreach ($_FILES['photo']['name'] as $key => $tmp_name) {

   $allowedExts = array("gif", "jpeg", "jpg", "png");
   $temp = explode(".", $_FILES["photo"]["name"][$key]);
   $extension = end($temp);

   if ((($_FILES["photo"]["type"][$key] == "image/gif")
    || ($_FILES["photo"]["type"][$key] == "image/jpeg")
    || ($_FILES["photo"]["type"][$key] == "image/jpg")
    || ($_FILES["photo"]["type"][$key] == "image/pjpeg")
    || ($_FILES["photo"]["type"][$key] == "image/x-png")
    || ($_FILES["photo"]["type"][$key] == "image/png"))
    && ($_FILES["photo"]["size"][$key] < 3000000)
    && in_array($extension, $allowedExts)) {

      /* GET File Variables */ 
      $tmpName = $_FILES['photo']['tmp_name'][$key]; 
      $fileType = $_FILES['photo']['type'][$key]; 
      $fileName = $_FILES['photo']['name'][$key]; 

      /* Start of headers */ 
      $headers = "From: $from"; 

      if (file($tmpName)) { 
        /* Reading file ('rb' = read binary)  */
        $file = fopen($tmpName,'rb'); 
        $data = fread($file,filesize($tmpName)); 
        fclose($file); 

        /* a boundary string */
        $randomVal = md5(time()); 
        $mimeBoundary = "==Multipart_Boundary_x{$randomVal}x"; 

        /* Header for File Attachment */
        $headers .= "\nMIME-Version: 1.0\n"; 
        $headers .= "Content-Type: multipart/mixed;\n" ;
        $headers .= " boundary=\"{$mimeBoundary}\""; 

        /* Multipart Boundary above message */
        $message = "This is a multi-part message in MIME format.\n\n" . 
                   "--{$mimeBoundary}\n" . 
                   "Content-Type: text/plain; charset=\"iso-8859-1\"\n" . 
                   "Content-Transfer-Encoding: 7bit\n\n" . 
                   $message . "\n\n"; 

        /* Encoding file data */
        $data = chunk_split(base64_encode($data)); 

        /* Adding attchment-file to message*/
        $message .= "--{$mimeBoundary}\n" . 
                  "Content-Type: {$fileType};\n" . 
                  " name=\"{$fileName}\"\n" . 
                  "Content-Transfer-Encoding: base64\n\n" . 
                  $data . "\n\n" . 
                  "--{$mimeBoundary}--\n"; 
      }
   } else {
     echo "Invalid File.";
   }
}

$sent = mail($to, $subject, $message, $headers);

if ($sent) {
  echo '<meta http-equiv="refresh" content="0;url=http://website.co.uk/html/thankyou.html">';
} else {
    echo "Sorry, we have encoutered a problem sending your message. Please try again or get in     touch via the contact page";
}

?>

理想情况下,我需要循环使用2种输入文件类型(第二种是可选的,因此如果用户只上传一张图像,它仍然可以工作)并将它们附加到一封电子邮件中。谢谢。

3 个答案:

答案 0 :(得分:0)

当你的循环运行时,它会从头开始重写$ message和$ headers变量,而不是连接。因此,当您实际发送电子邮件时,附件只有一个。

答案 1 :(得分:0)

$headers$message移至for循环之外。您已经在$message之外,但是您使用以下代码覆盖它:

 /* Multipart Boundary above message */
    $message = "This is a multi-part message in MIME format.\n\n" . 
               "--{$mimeBoundary}\n" . 
               "Content-Type: text/plain; charset=\"iso-8859-1\"\n" . 
               "Content-Transfer-Encoding: 7bit\n\n" . 
               $message . "\n\n"; 

应该是:

 /* Multipart Boundary above message */
    $message .= "This is a multi-part message in MIME format.\n\n" . 
               "--{$mimeBoundary}\n" . 
               "Content-Type: text/plain; charset=\"iso-8859-1\"\n" . 
               "Content-Transfer-Encoding: 7bit\n\n" . 
               $message . "\n\n"; 

PS:您可以像这样重定向PHP:

 header('Location: http://website.co.uk/html/thankyou.html');

另一个PS:您应该通过检查$_POST数组中设置的内容来确保不会出错,然后再尝试访问它们:

 $to = isset($_POST['myEmail']) ? $_POST['myEmail'] : NULL;

这是一个三元运算符,基本上是简写:

 if(isset($_POST['myEmail'])) {
   $to = $_POST['myEmail']
 } else {
   $to = NULL;
 }

答案 2 :(得分:0)

如果你正确地使用foreach循环来逐个获取每个上传的文件以便你可以处理它,你最终会得到类似的结果。

我还没有检查标题的实际内容是否正确我只是假设你说得对,但我确实简化了一些编码并删除了不必要的标量变量创建来保存$ _FILES数组中已经存在的数据在一个完全可用的状态。

/* a boundary string */
$randomVal = md5(time()); 

$allowedExts = array("gif", "jpeg", "jpg", "png");

/* Start of headers */ 
$headers = "From: $from"; 

$mimeBoundary = "==Multipart_Boundary_x{$randomVal}x"; 

/* Header for File Attachment */
$headers .= "\nMIME-Version: 1.0\n"; 
$headers .= "Content-Type: multipart/mixed;\n" ;
$headers .= " boundary=\"{$mimeBoundary}\""; 

/* Multipart Boundary above message */
$message = "This is a multi-part message in MIME format.\n\n" . 
           "--{$mimeBoundary}\n" . 
           "Content-Type: text/plain; charset=\"iso-8859-1\"\n" . 
           "Content-Transfer-Encoding: 7bit\n\n" . 
            $message . "\n\n"; 

foreach ($_FILES['photo'] as $filenumber => $file) {

   $temp = explode(".", $file["name"]);
   $extension = end($temp);

   if ( ($file["type"] == "image/gif"
      || $file["type"] == "image/jpeg"
      || $file["type"] == "image/jpg"
      || $file["type"] == "image/pjpeg"
      || $file["type"] == "image/x-png"
      || $file["type"] == "image/png" )
    && $file["size"]  < 3000000
    && in_array($extension, $allowedExts)) 
   {

      if ( file($file['tmp_name']) ) { 
        /* Reading file ('rb' = read binary)  */
        $fh = fopen($file['tmp_name'],'rb'); 
        $data = fread($fh,filesize($file['tmp_name'])); 
        fclose($fh); 

        /* Encoding file data */
        $data = chunk_split(base64_encode($data)); 

        /* Adding attchment-file to message*/
        $message .= "--{$mimeBoundary}\n" . 
                  "Content-Type: {$file['type']};\n" . 
                  " name=\"{$file['name']}\"\n" . 
                  "Content-Transfer-Encoding: base64\n\n" . 
                  $data . "\n\n" . 
                  "--{$mimeBoundary}--\n"; 
      }
   } // endif
} // endforeach