slim 4 - multiple file upload empty $_FILES array - php

I'm havong some trouble to upload multiple file at once in my vue and php app. I'm using slim to have an endpoint where upload request is posted:
On the server side I have this code to test if all works fine:
$app->post('/compress', function(Request $request, Response $response){
$files = $request->getUploadedFiles();
var_dump($files); // this will result in empty
//return $response;
});
In my javascript code, inside a vue method I have this code that is called when the file input will change:
let formData = new FormData();
for(let i; i < this.$refs.selectedImages.files.length; i++){
formData.append('images[]', this.$refs.selectedImages.files[i]);
}
let config = {
header: {
'Content-Type': 'multipart/form-data',
},
withCredentials: true
}
axios.post('http://localhost:3000/compress', formData, config)
.then( (response) => {
console.log(response, response.data);
});
tha result is that the var_dump will give me empty. How I can fix?

Can you try this one?
for( var i = 0; i < this.$refs.selectedImages.files.length; i++ ){
let file = this.$refs.selectedImages.files[i];
formData.append('images[' + i + ']', file);
}

After a lot of debug I've fixed the code. The problem was with the for() loop that seems not working to iterate FileList in my case. I've replaced it with a forEach() and voilà! The server started to get the uploaded files.
let files = this.$resf.selectedImages.files;
let formData = new FormData();
files.forEach( (el) => {
formData.append('images[]', el);
});

Related

How to receive $ FILES in PHP from Ionic?

I'm using FormData to send a file from ionic with angular to PHP, but in the PHP backend when you make var dump $_FILES appear empty.
This is my code in .ts:
file: File;
changeListener($event): void {
this.file = $event.target.files[0];
console.info(this.file); //First console info
const formData = new FormData();
const blobFile = new Blob([this.file], { type: this.file.type });
formData.append("file", blobFile, "filename");
this.myService.testing(formData).subscribe( resp => {
},(error)=>{
console.info(error);
})
}
In the service:
testing(data) {
return this.http.post(url, body, {headers: {'Content-Type': 'application/x-www-form-urlencoded'}})
}
The PHP Backed :
$postdata = file_get_contents("php://input"); // this shows me the contents of the file
var_dump($_FILES); // returns an empty array
So, what's my mistake? Am I sending badly from Ionic or am I getting bad in PHP ?
I'm using codeigniter 3
Thanks !

How to get file from Form Data in the server

I cant get the file data on the server. _$FILE says is empty. I do this trough ionic app. I send the information in http params.
cargarFoto(idnegocio,formData) {
let datos = new HttpParams()
.set("proceso", "subirImgNegocioApp")
.set("imgRestaurante", formData)
.set("idnegocio", idnegocio)
let headerOptions = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded');
return this.http.post(this.path,datos, {
observe: 'response',
responseType: 'text',
headers: headerOptions
});
}
That is the code from my service where i send the form Data and other information.
But when i use $_FILES to get the file, it says is null or empty. What im doing wrong? Actually all the information is get on $_POST. I returned post to the app and this is what displays:
body: "{
"proceso": "subirImgNegocioApp",
"imgRestaurante": "[object FormData]",
"idnegocio": "4"
}"
I can suggest little different approach - send everything as form data:
sendSomething(someVar: string, files: File[]) {
const formData = new FormData();
for (const f of files) {
formData.append('file[]', f);
}
formData.append('someVar', someVar);
return this.http.post('/someUrl', formData, {
headers: new HttpHeaders({ enctype: 'multipart/form-data' })
});
}
Then in PHP:
$someVar = $_REQUEST['someVar']
And files (or one file) will be in
$_FILES['file']

How to send both a file and JSON data to the server

tl;dr:
Using Angular 6 on the front end and PHP with Phalcon on the backend, I can send JSON data or a File with no problem but I am having a problem sending both in the same request.
Previously I was sending JSON data to the server using something like this
const HTTP_OPTIONS = {
headers: new HttpHeaders({
'Content-Type': 'application/json'
}),
observe: 'response'
};
post(endPoint: string, body: object): Observable<any> {
return this.http.post<any>(this.apiUrl + endPoint, body, HTTP_OPTIONS)
.pipe(
tap(result => this.log(JSON.stringify(result, null, 2))),
catchError(this.handleError('post', []))
);
}
And I was able to get the data from PHP using Phalcon with
$app = new \Phalcon\Mvc\Micro();
$app->post('/upload', function() use ($app) {
$input = $app->request->getJsonRawBody();
// $input now contains my JSON data
});
Some time later, I needed to send a file so I used this answer with some minor modifications:
postFile(fileToUpload: File, endpoint: string): Observable<any> {
const formData: FormData = new FormData();
formData.append('fileKey', fileToUpload, fileToUpload.name);
return this.httpClient
.post(endpoint, formData, { headers: {'Authorization': this.jwt} }).pipe(
tap(result => this.log(JSON.stringify(result, null, 2))),
catchError(this.handleError('post', []))
);
}
And I received my file with no problems using the documentation as a guide:
$app->post('/uploads', function() use ($app) {
if ($app->request->hasFiles() == true) {
foreach ($app->request->getUploadedFiles() as $file) {
$file->moveTo('files/' .$file->getname());
}
} else {
$app->response->setStatusCode(400)->sendHeaders();
$app->response->setJsonContent(['error' => 'no file']);
return $app->response;
}
});
The problem: Now I would like to send both a file and some JSON data at the same time. I can always just upload the file and then send the data separately but I don't think that's the right way to do it. I don't want to make more than the minimum number of network calls.
What I've tried: Using the file upload code and simply appending another field to my FormData object with my JSON data
formData.append('fileKey', fileToUpload, fileToUpload.name);
formData.append('data', JSON.stringify(data));
and a variation of that
formData.append('fileKey', fileToUpload, fileToUpload.name);
formData.append('data', new Blob([JSON.stringify(data), {type: 'application/json'}]);
Either way, on the backend I can get the file but $app->request->getJsonRawBody and $app->request->getRawBody are empty.
I also tried using the original JSON-sending code and just changing a bit to include the file but with no success.
post(fileToUpload: File, data: CustomData): Observable<any> {
this.messageService.add('uploaded file');
const formData: FormData = new FormData();
formData.append('fileKey', fileToUpload, fileToUpload.name);
formData.append('data', JSON.stringify(data), 'data');
return this.http
.post(this.apiUrl + 'uploads/', {'data': data, 'file': fileToUpload}, HTTP_OPTIONS).pipe( // file is empty on the server like this
tap(result => this.log('POST file :\n' + JSON.stringify(result, null, 2))),
catchError(this.handleError('post', [], 'fileUpload'))
);
}
I can easily send either my JSON data or the file but not both.
I searched the Phalcon documentation and several QAs on sending files and/or JSON with Angular but I cannot figure out how to make this work.
You are sending json as text in post request, so instead of $app->request->getJsonRawBody you should try something like
$rawJson=$app->request->getPost('data');
$object=json_decode($rawJson);
you can get your json as #Błażej Kowalczyk said
$this->request->getPost()
and you can check for files and get them
if ($this->request->hasFiles()) {
foreach ($this->request->getUploadedFiles() as $file) {
// $file is an instance of Phalcon\Http\Request\File
var_dump($file->getName());
}
}
check these pages for more information
https://docs.phalconphp.com/3.4/en/api/phalcon_http_request
https://docs.phalconphp.com/3.4/en/api/phalcon_http_request_file

Angular 2 http.post FormData() to PHP to upload a file

I have a project using A2 CLI, and I'm trying to upload a file using an input tag with type="file". I have things functioning as far as the overall workflow goes, but I am having trouble getting the file data from client to server.
I have the following code in TypeScript:
myFnc(event){
let fileList: FileList = event.target.files;
if(fileList.length > 0) {
let file: File = fileList[0];
console.log(file);
console.log(file.name);
let formData:FormData = new FormData();
formData.append('uploadFile', file, file.name);
let headers = new Headers();
/*
this was the culprit:
headers.append('Content-Type', 'multipart/form-data');
worked for me by changing it to:
*/
headers.append('enctype', 'multipart/form-data');
headers.append('Accept', 'application/json');
let options = new RequestOptions({ headers: headers });
console.log(formData);
console.log(options);
this.http.post('./assets/data/upload-persona-document.service.php', formData, options)
.map(res => res.json())
.catch(error => Observable.throw(error))
.subscribe(
data =>{
console.log(data);
},
error =>{
console.log(error);
}
)
}
}
I get no errors and get the results I'm inspecting in the console. (I understand that the console.log(formData) won't actually output formData's contents. I've tried .entries() but I've read that FormData methods are not well supported in TS.)
In upload-persona-document.service.php:
<?php
$target_dir = "../docs/Personas/";
$json = array();
$postData = file_get_contents("php://input");
$input = json_decode($postData);
$json['input'] = $input;
$json['post'] = ($_POST);
$json['files'] = $_FILES;
$target_file = $target_dir . basename($_FILES["uploadFile"]["name"]);
$uploadOk = 1;
$imageFileType = pathinfo($target_file,PATHINFO_EXTENSION);
echo json_encode($json);
// ...a bunch of code that will act on the data when I can finally get it correctly...
When I get the response back, I get:
[Log] {input: null, post: [], files: []} (main.bundle.js, line 1117)
I'm stumped at what I'm missing.
So after a bit more digging and experimentation it turned out that I had to change Content-Type to enctype in the headers.append() line above (updated that bit.)

Laravel 5 - $request->file returns null

I'm sending some images from an angularjs client to a laravel server. Debugging the image data shows that it's a correct object, but someshow Laravel can't process it with
$request->file('uploaded_file').
Logging $scope.upload shows
Then I send $scope.upload[0] as a post data to the server via $http.
data: {
uploaded_file: $scope.upload[0]
}
On Laravel, what I did was:
$files = $request->file('uploaded_file');
dd($files);
Which returns null. What am I missing here?
If your post looks like my code then it will be all right.
I think that you send the selected file directly.And don't pass it through the
new FormData();
$scope.fileChanged = function(event) {
var file = event.target.files[0];
console.log(file);
var fd = new FormData();
fd.append('file', file);
$http.post("test.php",fd, {
headers: {'Content-Type': undefined,'Process-Data': false}
}).success(function(responseData) {
console.log(responseData);
});
}

Categories