1

I'm trying to attach a file to an email that is inside of a JSON object being posted to my PHP script.

The posted JSON appears as:

{  
   data:{  
      "sendto":"[email protected]",
      "name":"John Smith",
      "contem":"[email protected]",
      "mess":"This is a test",
      "subj":"Test"
   },
   file:{  
      "webkitRelativePath":"",
      "lastModified":1389280265000,
      "lastModifiedDate":"2014-01-09T15:11:05.000Z",
      "name":"test.pdf",
      "type":"application/pdf",
      "size":6437
   }
}

My PHP handles all of the "data" attributes just fine, but when I try to check for the file, I get:

Notice:  Undefined index: file in My\Website\Location\script.php on line 20

And Line 20 is:

$file = $_FILES['file'];

Is this index undefined because it's within a JSON object?

I've also tried:

$file = $_FILES[json_decode(stripslashes($_POST['file']), true)];

Thinking since the file is within a JSON object, it first needs decoded. However, this returned:

Warning:  Illegal offset type in My\Website\Location\script.php on line 20

I think the issue for the illegal offset had something to do with trying to set $_FILES to a JSON object, yes?

When I try to simply set the $_POST['file'] into the $_FILES array:

$file = $_FILES[$_POST['file']];

I receive:

Notice:  Undefined index: {"webkitRelativePath":"","lastModified":1389280265000,"lastModifiedDate":"2014-01-09T15:11:05.000Z","name":"test.pdf","type":"application/pdf","size":6437} in My\Website\Location\script.php on line 20

Showing the uploaded file as a JSON object.

What am I missing here? How can I get the uploaded file from my AJAX post?

ANSWER

As noted about the multiform/form-data content type, I changed the way I sent the form data.

Rather than using an object with a file inside of it:

var d = new FormData();
var data = {};
data.sendto = '[email protected]';
data.name = $('#puName').val();
data.contem = $('#puEmail').val();
data.mess = $('#puMess').val();
data.subj = 'User Permissions';
d.append('data', JSON.stringify(data));
$.each($('#puFile')[0].files, function(i, file) {
     d.append('file-'+i, file);
});
sendEmail(d);

I sent a FormData object directly to the PHP script.

function sendEmail(d){
    $.ajax({
        url: "script.php",
        data: d,
        cache: false,
        contentType: false,
        processData: false,
        type: 'POST',
        success: function () {
            alert("Cool");
        },
        error: function (e) {
            alert("Not Cool");
        }
    });
}

The FormData was made of an JSON object for my data, and the selected File.

PHP then read the form data like:

$data = json_decode(stripslashes($_POST['data']), true);
$file = $_FILES['file-0'];

Now my email is sending correctly.

1
  • Your JSON is badly formed. Test is at jsonlint.com Commented Dec 29, 2014 at 18:07

2 Answers 2

4

$_FILES superglobal will only be created when multipart/form-data content-type is set for the POST and would include the actual file being POSTed, not a local reference to that file. Instead you are sending a JSON request (hopefully with an appropriate application/json content-type). This is not going to populate $_FILES. Unless your receiving script has the ability to take the path information provided and access the file in question, your POSTing script will actually need to send the file as part of the POST.

Uploading files via AJAX is best handled using specific AJAX upload libraries that are meant to do this, which basically utilize workarounds to the fact that you really can't POST a file asynchronously natively in browsers.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks - so rather than creating an object with my form components, I should 1. Submit my entire form to the PHP script, and 2. Change my contentType in my AJAX post to "multipart/form-data"?
This is probably THE authoritative SO post about asynschronous file upload - stackoverflow.com/questions/166221/… Read the first few answers for very important considerations on what you are trying to do.
This answer put me on the right path. See above for changes made to get this to work.
0

Have you tried something like this -

Copy the json code in a variable say 'a' and then, decode it i.e. json_decode(a), then a->file

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.