Uploading an image with ajax (PUT): Can't recieve file via getParsedBody/ getUploadedFiles

Hello,

I’m trying to send a file from an <input> Element via jQuery’s Ajax to my Controller in Slim.
The request reaches my controller function which handles the PUT request.
But where is the file?
Tried it with this code in my controller:

function putImage(Request $request, Response $response, array $args){
        $fileName = $args['name'];
        $recipeID = $args['id'];

        echo var_dump($request->getUploadedFiles()); // prints empty array
        echo var_dump($request->getParsedBody()); // prints null
        echo var_dump($_POST); // i know it's a PUT request.. just trying (prints empty array)
        echo var_dump($_FILES); //prints empty array

       return $response->withStatus(400); //triggers the console to write
}

I got the right statuscode back, but all echos print either null or an empty array in my console. So where is my file? :confused:

Did this, to send the data (jQuery):

`var file = document.getElementById("fileInput").files[0];`
 var formData = new FormData();
 formData.append('file', file);

        $.ajax({
            type: 'PUT',
            url: url,
            data: formData,
            cache: false,
            contentType: 'multipart/form-data',
            processData: false,
            success: function(data){
                console.log("success");
                console.log(data);
            },
            error: function(data){
                console.log("error");
                console.log(data);
            }
        });

I’m using Chrome version 57, so FormData.append() shouldn’t be a problem…

Would be great if somebody could help me.
Tried it in various other ways: base64 encoding the file from an canvas element and sending this dataURI to my server. Got somehow an image/png with transparent content, but the file was reachable via $request->getParsedBody()['file']. So I’m wondering why it is not reachable now.

With a normal synchron submit of a form it worked, but the goal is to send each new image on the change event of my file input via PUT asynchronously to the server, which then stores the file.

If someone has an idea to reach that goal with an other solution it would be nice to hear about it :smiley:
Hope you guys can help me! :slight_smile:

Greetings
Alex

All these methods and variables you are trying to use are only populated when PHP receives a POST request.

To access the body of a PUT request you can use $request->getBody->detach(), or open the standard input manually: fopen('php://input', 'r'). Keep in mind that in both cases you’ll get a resource, not a string. You can then get the actual content with stream_get_contents.

There’s some more information regarding PUT requests in the PHP website: http://php.net/manual/en/features.file-upload.put-method.php

Great, thank you! :slight_smile:
It’s working now:

function putImage(Request $request, Response $response, array $args){
        $fileName = $args['name'];
        $recipeID = $args['id'];

        if (!($putData = fopen("php://input", "r")))
            throw new \Exception("Can't get PUT data.");

        $path = $this->fileHandler->createImagePath($recipeID, $fileName);
        $destination = fopen($path, 'w');
        stream_copy_to_stream($putData, $destination);
        $imageType = exif_imagetype($path);

        if (!($imageType == 3 || $imageType == 2 ||$imageType == 1)){ //png or jpeg or gif?
            unlink($path);
            echo $imageType;
            return $response->withStatus(400);
        }

        fclose($putData);
        fclose($destination);

        return $response->withStatus(201);
    }

Many thanks! :slight_smile: