How to get file from Form Data in the server - php

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']

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 !

The variables never reach PHP from the FETCH API

I have 3 files (HTML,JS and PHP) in the HTML save de info in variable called DatosPaciente in JavaScript
function Tomar_DATOS(){
DatosPaciente={
id:document.getElementById("paciente_id").value,
fecha:document.getElementById("fecha").value
};}
Then i use a function called Tiene_Cita_Hoy inside of a JS file
Tiene_Cita_Hoy(DatosPaciente)
in the JS file i try to use the Fetch API to send info to the PHP file
function Tiene_Cita_Hoy(Datos){
console.log(Datos);//"{id: "8", fecha: "2020/09/03"}" here everything is fine
fetch('tiene_cita.php',{
method: 'POST',
body: Datos
})
.then(res => res.json())
.then(data => {
console.log(data); //to see the result
})
}
then in a PHP file, then tried to receive the information via POST
$VALOR_id_paciente=$_POST['id'];
$VALOR_fecha=$_POST['fecha'];
and then I assign those values ​​to a query
$SQL="SELECT * FROM vhsagenda WHERE PACIENTE='".$VALOR_id_paciente."' AND FECHA='".$VALOR_fecha."'";
echo json_encode($SQL);//just to see what information have
but the result is always: SELECT * FROM vhsagenda WHERE PACIENTE='' AND FECHA=''
apparently the information never reaches the PHP file
I have made some proper way for this method to get working.
You need to make an object first, then pass it in 'for loop'. It will generate string like this for example (test=123&test_two=444)
async function catch_something(url, bodyContent = {test: 123, test_two: 444}){
let bodyContent_string = '';
if(bodyContent instanceof Object){
for(const form_key of Object.keys(bodyContent)){
if(form_key != Object.keys(bodyContent)[Object.keys(bodyContent).length - 1]){
bodyContent_string += `${form_key}=${bodyContent[form_key]}&`;
}else{
bodyContent_string += `${form_key}=${bodyContent[form_key]}`;
}
}
}
const response = await fetch(url, {
method: 'POST',
mode: 'cors',
cache: 'no-cache',
headers: {
'X-Requested-With': 'XMLHttpRequest',
'Content-Type': 'application/x-www-form-urlencoded'
},
body: bodyContent_string
}).catch((error) => {
console.error('Error:', error);
});
if(!response.ok){
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
}
You should send the parameters as a URL-encoded string.
function Tomar_DATOS(){
DatosPaciente = 'id=' + encodeURIComponent(document.getElementById("paciente_id").value) + '&fecha=' + encodeURIComponent(document.getElementById("fecha").value);
}
You've passed a plain object to the body parameter, but fetch doesn't know what to do with that data type (so it converts it to the useless string "[object Object]").
You should pass something that fetch knows how to convert into something supported by PHP instead.
e.g. a FormData object.
DatosPaciente = new FormData(document.getElementById("form_containing_your_inputs"));

React Native uploading Image to php page on server

I have PHP page on a web server to upload image from React Native.
Using Postman method POST, form-data key:avatar value: image_file everything works as expected.
In React Native I tried:
let uploadData = new FormData();
uploadData.append('avatar', uploadUri);
fetch(base_url, { method: 'post,', body: uploadData }).then(
(res) => {
var myresponse = res;
console.log(JSON.stringify(myresponse));
//console.log(res);
}
);
I am getting from server error:
{"type":"default","status":400,"ok":false,"headers":{"map":{"server":"Apache","connection":"Upgrade,
close","content-type":"text/html","vary":"Accept-Encoding,User-Agent","date":"Wed,
20 May 2020 15:29:15
GMT","accept-ranges":"bytes","upgrade":"h2,h2c"}},"url":"http://www./uploadImage.php","_bodyInit":{"_data":{"size":10154,"offset":0,"blobId":"D8041FEE-0479-4CD5-8438-4EFD737561DE","type":"text/html","name":"uploadImage.php","__collector":{}}},"_bodyBlob":{"_data":{"size":10154,"offset":0,"blobId":"D8041FEE-0479-4CD5-8438-4EFD737561DE","type":"text/html","name":"uploadImage.php","__collector":{}}}}
Than I tried using axios:
let uploadData = new FormData();
uploadData.append('avatar', uploadUri);
axios.post(base_url, uploadData).then((res) => {
console.log(res);
});
I get this response from the server:
"error": true,
"message": "No file was sent!",
"status": "error",
It is failing on: if($_FILES['avatar']), in PHP.
I have no idea what to do any more, again in Postman everything works fine as expected.
Does anybody have any idea what to do?
I tested it again and it is to be a problem with the URI that I am sending, for sure.
ie. if I look in Postman the request that I am sending:
avatar=#/Users/......image.jpg
and in React Native I am sending:
"avatar","file:///Users/.....image.jpg
By the way, I am using expo-image-picker to select the image.
It looks like this did the work..
let body = new FormData();
//Appending file to body
body.append('avatar', {
uri: uploadUri,
type: 'image/jpeg', //This is the file type .. you can define according to your requirement
name: 'avatar.jpg', //File name you want to pass
});
//Service call
fetch(base_url, {
method: 'POST',
headers: new Headers({
'Content-Type': 'application/x-www-form-urlencoded',
}),
body: body,
})
.then((res) => res.json())
.then((responseJson) => {
//GET RESPONSE SUCCESS OF FAILURE
console.log(JSON.stringify(responseJson));
})
.catch((error) => {
//ERROR
console.log(JSON.stringify(error));
});

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

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