18

I'm using standard PHP functions to upload a file for use as an attachment with PHPMailer.

<form name="upload" method="post" action="send_form_email3.php">
    <div width="100%" class="con3">
        <div class="lable">
            <label for="first_name">First Name *</label>
        </div>
        <input  type="text" name="first_name" id="first_name" class="span4">

        <div class="lable">
            <label for="email">Email Address *</label>
        </div>
        <input  type="text" name="email" id="email" class="span4">

        <div class="lable">
            <label for="telephone">Contact Number *</label>
        </div>
        <input  type="text" name="telephone" id="telephone" class="span4">

        <div class="lable">
            <label for="comments">Message *</label>
        </div>
        <textarea  name="comments" rows="8" id="comments" class="span4"></textarea>

        <div class="lable">
            <label for="upload">Send Us Your CV *</label>
        </div>
        <input type="file" name="upload" id="upload" />

        <input type="submit" value="Submit" class="btn btn-success">
    </div>
</form>

This form gets submitted to the following php handler where the mail is built and sent:

<?php

    require_once("class.phpmailer.php");

    $first_name = $_POST['first_name']; // required
    $email_from = $_POST['email']; // required
    $telephone = $_POST['telephone']; // required
    $comments = $_POST['comments']; // required

    echo "just got form values<br />";
    echo $_FILES['upload']['name'].'<br />';

    $email_message = "Form details below.<br />";

    function clean_string($string) {
      $bad = array("content-type","bcc:","to:","cc:","href");
      return str_replace($bad,"",$string);
    }

    $email_message .= "Name: ".clean_string($first_name)."\n";
    $email_message .= "Email: ".clean_string($email_from)."\n";
    $email_message .= "Contact: ".clean_string($telephone)."\n";
    $email_message .= "Message:\n".clean_string($comments)."\n";

    echo "added text to email<br />";

    $target_path = "uploads/";

    $target_path = $target_path . basename( $_FILES['upload']['name']); 

    // upload the file
    echo "target = ".$target_path."<br />";

    if (isset($_FILES['upload']['size']))
    {
        if ($_FILES['upload']['size'] > 0)
        {
        echo 'file size: '.basename($_FILES['upload']['size']).'<br />';
            if (move_uploaded_file($_FILES['upload']['name'], $target_path))
            {
                echo "The file ".  basename( $_FILES['upload']['name'])." has been uploaded<br />";
                                    // adding an already existing file as an attachment to the email for debugging purposes.
                $email->AddAttachment('uploads/CreditReportViewer.pdf');
            }
            else
            {
                echo "There was an error uploading the file, please try again!<br />&nbsp;".basename($_FILES['upload']['error']);
            }
        }
        else
        {
            echo "There was an error uploading the file, please try again!<br />";
        }
    }
    else
    {
        echo "No file was found for the upload.<br />";
    }


    $email = new PHPMailer();

    $email->To = "me@this.com";
    $email->From = $email_from;
    $email->FromName = $first_name;
    $email->Subject = "New Message from Website";
    $email->Body = $email_message;

    echo "\n mail built...<br />";

    $email->Send();

    echo "mail sent!";
?>

The problem is that $_FILES['upload']['name'] is not set. Here's the echoes that are being written to the browser:

just got form values

added text to email
target = uploads/
No file was found for the upload.
mail built...
mail sent!

This makes me think that I'm referencing the file upload field or the upload itself incorrectly.

Can anyone see any problems here or provide some guidance if this isn't the best way to do this?

Ortund
  • 8,095
  • 18
  • 71
  • 139

6 Answers6

47

You have to add,

enctype= "multipart/form-data"

Change your form to,

<form name="upload" method="post" action="send_form_email3.php" enctype= "multipart/form-data">
Edwin Alex
  • 5,118
  • 4
  • 28
  • 50
  • I was banging my head for the same error since 2 hours in spite of having mastered image uploads in last 3 years, and turns out i didn't write `enctype`. Feels so stupid.. – coder101 Dec 27 '14 at 15:26
  • This helped me after tearing my hair out all afternoon. But strangely enough, I am sure it used to work without this. – Antony D'Andrea Feb 12 '15 at 15:39
7

add enctype to your form: change:

<form name="upload" method="post" action="send_form_email3.php">

to

<form name="upload" method="post" action="send_form_email3.php" enctype="multipart/form-data">
Sudhir Bastakoti
  • 99,167
  • 15
  • 158
  • 162
7

Another tip: if the upload_max_filesize (php.ini) is less than the file selected by user, $_FILES will be empty.

celsowm
  • 846
  • 9
  • 34
  • 59
3

You forget to set multipart in form declaration.

add enctype="multipart/form-data" in form.

Dipesh Parmar
  • 27,090
  • 8
  • 61
  • 90
3

You should add enctype=multipart/form-data to your form.

<form name="upload" method="post" action="send_form_email3.php" enctype="multipart/form-data">

Because it's transmitted as a MIME stream, a very different format than a normal POST

What does enctype='multipart/form-data' mean?

Community
  • 1
  • 1
Techie
  • 44,706
  • 42
  • 157
  • 243
  • Awesome, the file is being uploaded now... sort of... The upload still fails though... i.e. `if (move_uploaded_file($_FILES['upload']['name'], $target_path))` returns false. No clues in apache's error log though... – Ortund Feb 28 '13 at 08:00
0

If you added the enctype and still doesn't work - check the PHP file permissions. in ooowebhost you can find it in chmod. change to '777'. otherwise, the file doesn't have permissions to execute/write

Maoritzio
  • 387
  • 1
  • 6
  • 8