4

Im pulling my hair out on this one. Is there any way to parse form-data in Slim PHP that puts the data into an array (as you would JSON). I might be missing something but everything I have tried has kicked the data out in one array with no way of targeting the form data. Any help appreciated.

Angular Component (executes on form submit):

let memory: any = new FormData();

if (this.memory_images) {
  for(var i = 0; i < this.memory_images.length; i++) {
    memory.append('memory_images', this.memory_images[i], this.memory_images[i].name);
  }
}
memory.append('memory_song', this.memory_song);
memory.append('memory_text', this.memory_text);
memory.append('memory_author', this.memory_author);
memory.append('memory_collection', this.memory_collection);

this.memoriesService.saveMemory(memory).subscribe(data => {
  console.log(data);
  // returns empty array
});

Angular memoriesService:

saveMemory(memory){
  let headers = new Headers();
  headers.append('Content-Type','multipart/form-data');
  return this.http.post('http://{{ my api route }}/api/v1/memories', memory, {headers: headers})
  .map(res => res);
}

Slim API Route:

$app->group(APIV1 . '/memories', function() {
  $this->post('', function (Request $request, Response $response, $args) {
    var_dump($request->getParsedBody());
    return $response
  });
});

The component always returns an empty array. Interestingly, when submitting the form data via Postman the data is returned but as a string in an array (I've only sent two parameters):

array(1) {
  ["------WebKitFormBoundaryXcRTrBhJge4N7IE2
  Content-Disposition:_form-data;_name"]=>
    string(181) ""memory_author"

    Jack
    ------WebKitFormBoundaryXcRTrBhJge4N7IE2
    Content-Disposition: form-data; name="memory_collection"

    12345678
    ------WebKitFormBoundaryXcRTrBhJge4N7IE2--
   "
}

The form was working until I needed to add the ability to upload an image. Before, I collected the form inputs into an object and sent to the API as JSON. Its my understanding that because I now need to attach files, I need to send the submission as form-data. Is this correct? THANK YOU!!!

2
  • Sorry haven't understood it good...So the PHP part is making the problems here? Commented May 23, 2017 at 16:54
  • Hello Arslan, Im not entirely sure whats going wrong. In my opinion theres three possibilities: 1. I am using the JS FormData object incorrectly 2. Slim cannot parse form data or 3. Angular is not managing the form-data request correctly or I'm not using it correctly. Commented May 23, 2017 at 17:51

2 Answers 2

2

I faced the same issues in Angular and Slim API and Now its working Perfectly make theses things

1- Do not send any header in your request from angular code

2- For uploaded photos You will get the uploading image in Slim app In $files array This is an example to upload image from angular to Slim API

In your component.ts

uploadimage(){
var formData = new FormData();
formData.append("image",this.image );
return this.http.post('http://Yourserver.com/UploadeFileAPI',formData)
.map(response =>response.json()).subscribe(
result=>{
console.log("image uploaded");
},
error=>{
console.log(error);
})}

in Your Slim app

$app->post('/uploadphoto',function ($req,$res){
$topic_name=$req->getParsedBodyParam('any parm name');
$files=$req->getUploadedFiles();
$newimage=$files['image'];}
Sign up to request clarification or add additional context in comments.

1 Comment

YES! Thank you for your help Ramy. A combination of removing the header in Angular and Slim's getUploadedFiles function was what I needed. What does removing the header do for Slim? Does it default to something else?
0

From Slim's perspective, it simply sets the parsed body to whatever is in $_POST, so this means that either:

  • the method isn't POST
  • the content-type type isn't one of application/x-www-form-urlencoded or multipart/form-data
  • PHP could not parse the sent data into an array

Looking at your code, I think we can rule out the first two, which implies that implies that the data is being sent in a format that PHP doesn't understand.

It looks like you're trying to send multiple files, so I think that maybe you need to change:

memory.append('memory_images', this.memory_images[i], this.memory_images[i].name);

to:

memory.append('memory_images[]', this.memory_images[i], this.memory_images[i].name);

(i.e. it's an array and needs the [].)

3 Comments

Hello Rob, thank you for your response. I have made the amend above but the Angular component is still logging: _body: "array(0) {↵}↵". When I send the data via Postman I'm still receiving the same response (see above). Is this expected behaviour for Slim in response to form-data? I would assume it would parse the data into an array. I suspect the issue is two part: Angular is not sending the form-data correctly (as the Slim API is not receiving anything) and Slim does not parse form data correctly (based on Postman response).
Please provide a curl command and its output that shows the problem.
Many thanks for your help Rob, much appreciated. As per Ramy's suggestion above, it looks like Slim cannot parse form data correctly as after removing the content type header in Angular, it immediately worked for my text data. Then it was just a case of using the getUploadedFiles function to grab the files.

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.