In php, I cannot access the uploaded files in $_FILES instead they appear in $_POST["imgs"] as [object File] without any properties like name.
How can I get those files accessed in $_FILES?
import React, { useCallback } from 'react'
import { useDropzone } from 'react-dropzone'
import axios from 'axios'
const imgAjaxUploader = axios.create({
baseURL: 'http://localhost',
timeout: 1000,
headers: { 'Content-Type': 'mulipart/form-data' }
});
export default function ImgDropzone() {
const onDrop = useCallback(acceptedFiles => {
const formData = new FormData()
formData.append('imgs', acceptedFiles)
try {
imgAjaxUploader.post('/store/admin/imgHandler.php', formData, {
headers: {
'Content-Type': 'mulipart/form-data'
}
}).then(data =>
console.log(data)
).catch(err => {
console.log(err)
return null
})
} catch (err) {
alert(err)
}
}, [])
const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop: onDrop, accept: 'image/jpeg, image/png' })
return (
<div {...getRootProps()} style={{ display: "inline-block" }}>
<input {...getInputProps()} />
{
isDragActive ?
<p>Drop the files here ...</p> :
<p>Drag 'n' drop some files here, or click to select files</p>
}
</div>
)
}
I found the solution. Multiple files need to be appended to the same name with a trailing [], in order to be compatible with PHP:
acceptedFiles.forEach(file => {
formData.append('imgs[]', file)
})
resource example 3
Related
I made login with PHP and React Native but now I want to display the ID of the user that's logged in. The ID should be showed on the screen that appears when the user is logged in.
I tried several things but I think the way I request the props is wrong. Because the page where I want to show never requests the data that is started in the previous page.
This is the login screen:
import React from 'react';
import { StyleSheet, Text, View, TextInput, Button } from 'react-native';
import * as Expo from 'expo';
export default class App extends React.Component {
state = {
username: '',
password: '',
response: '',
users_ID: '',
};
handleusers_usernameChange = (users_username) => {
this.setState({ users_username });
};
handleusers_passwordChange = (users_password) => {
this.setState({ users_password });
};
handleLoginPress = async () => {
const { users_username, users_password } = this.state;
try {
let response = await fetch('http://IP/CodingApp/login.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
users_username,
users_password,
}),
});
let responseJson = await response.json();
console.log(responseJson);
if (responseJson.loggedin) {
this.props.setLoggedIn(true, responseJson.users_ID);
this.setState({ users_ID: responseJson.users_ID });
} else {
this.setState({ response: 'tekst kwam niet overeen' });
}
} catch (error) {
console.error(error);
}
};
render() {
return (
<View style={styles.container}>
<TextInput
style={styles.input}
value={this.state.users_username}
onChangeText={this.handleusers_usernameChange}
placeholder="users_username"
/>
<TextInput
style={styles.input}
value={this.state.users_password}
onChangeText={this.handleusers_passwordChange}
placeholder="users_password"
secureTextEntry
/>
<Button title="Login" onPress={this.handleLoginPress} />
<Text>{this.state.response}</Text>
</View>
);
}
}
And this is the screen that appears after the user is logged in:
import React from 'react';
import { View, Text } from 'react-native';
const EditFamily = (props) => {
return (
<View>
<Text>Your user ID is: {props.users_ID}</Text>
</View>
);
};
export default EditFamily;
Read about redux, which is a state management tool, you can save id whenever or wherever you go and use it everywhere.
https://redux.js.org/introduction/getting-started
i use Laravel-filepond and Vue FilePond.
but FilePond send a blank request to server.
this is my codes:
*UserComponent.vue
<template>
<div class="container">
<file-pond
name="Profile"
ref="pond"
label-idle="drag & drop"
v-bind:allow-multiple="false"
accepted-file-types="image/jpeg, image/png"
v-bind:files="userFile"
v-bind:server="{
url: '/panel/filepond',
timeout: 7000,
process: {
url: '/process',
method: 'POST',
headers: {
'X-CSRF-TOKEN': this.get_meta('csrf-token'),
},
}
}"
v-on:init="handleFilePondInit"/>
</div>
</template>
<script>
import vueFilePond, {setOptions} from 'vue-filepond';
import 'filepond/dist/filepond.min.css';
import 'filepond-plugin-image-preview/dist/filepond-plugin-image-preview.min.css';
import FilePondPluginFileValidateType from 'filepond-plugin-file-validate-type';
import FilePondPluginImagePreview from 'filepond-plugin-image-preview';
import FilePondPluginImageEdit from 'filepond-plugin-image-edit';
const FilePond = vueFilePond(FilePondPluginFileValidateType, FilePondPluginImagePreview);
export default {
data() {
return {
userFile: [],
}
},
methods: {
handleFilePondInit: function () {
console.log('FilePond has initialized');
}
},
components: {
FilePond
},
}
</script>
FilePondController.php Original file
<?php
namespace Sopamo\LaravelFilepond\Http\Controllers;
use function dd;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller as BaseController;
use Sopamo\LaravelFilepond\Filepond;
class FilepondController extends BaseController
{
private $filepond;
public function __construct(Filepond $filepond)
{
$this->filepond = $filepond;
}
public function upload(Request $request)
{
dd($request->all());
}
}
when I upload a file on client side (in default response with 422), I can not find it on my server.
FrameWorks & Repository is on last version.
Response
[]
According to the author, you are sending the metadata instead of the file itself. I solved this using the advanced custom process function that you can found in documentation. There you can find the comments about what almost every part of the code does.
data() {
return {
server: {
url: 'http://base-url.test',
process: (fieldName, file, metadata, load, error, progress, abort, transfer, options) => {
const formData = new FormData();
formData.append(fieldName, file, file.name);
const request = new XMLHttpRequest();
request.open('POST', 'url-to-post-to');
request.setRequestHeader('X-CSRF-TOKEN', 'your-csrf-token');
request.upload.onprogress = (e) => {
progress(e.lengthComputable, e.loaded, e.total);
};
request.onload = function () {
if (request.status >= 200 && request.status < 300) {
load(request.responseText);
} else {
error('Error');
}
};
request.send(formData);
return {
abort: () => {
request.abort();
abort();
},
};
},
},
}
},
Then you only need to bind it:
<template>
<div class="container">
<file-pond
name="Profile"
ref="pond"
label-idle="drag & drop"
v-bind:allow-multiple="false"
accepted-file-types="image/jpeg, image/png"
v-bind:files="userFile"
v-bind:server="server"
v-on:init="handleFilePondInit" />
</div>
</template>
responseText is the unique Id from the server. Maybe you want to emit it to parent component:
data() {
return {
server: {
url: 'http://base-url.test',
process: (fieldName, file, metadata, load, error, progress, abort, transfer, options) => {
const thisReference = this;
// Other code
request.onload = function () {
if (request.status >= 200 && request.status < 300) {
thisReference.
thisReference.$emit('my-event', request.responseText);
load(request.responseText);
} else {
error('Error');
}
};
// Other code
},
},
}
},
Pretty similar if you want to know what file has been reverted (in this case, you need to response from server with the same id you sent):
data() {
return {
server: {
// Process, url, etc.
revert: {
url: '/url-to-delete',
method: 'DELETE',
headers: {
'X-CSRF-TOKEN': 'your-csrf-token'
},
onload: (idDeleted) => this.$emit('my-event', idDeleted)
},
},
}
},
I'm making a mobile application using expo client to allow user to upload image or take from a camera and then the image saves on my local server on PHP / Database MySQL. How do I do that thing if I'm using an expo?
for example code in react native (saving to PHP local server but not save database)
import React, { Component } from 'react';
import {
ActivityIndicator,
Button,
Clipboard,
Image,
Share,
StatusBar,
StyleSheet,
Text,
TouchableOpacity,
View,
} from 'react-native';
import { Constants } from 'expo';
import * as ImagePicker from 'expo-image-picker';
import * as Permissions from 'expo-permissions';
export default class App extends Component {
state = {
image: null,
uploading: false,
};
render() {
let {
image
} = this.state;
return (
<View style={styles.container}>
<StatusBar barStyle="default" />
<Text
style={styles.exampleText}>
Example: Upload ImagePicker result
</Text>
<Button
onPress={this._pickImage}
title="Pick an image from gallery"
/>
<Button onPress={this._takePhoto} title="Take a photo" />
{this._maybeRenderImage()}
{this._maybeRenderUploadingOverlay()}
</View>
);
}
_maybeRenderUploadingOverlay = () => {
if (this.state.uploading) {
return (
<View
style={[StyleSheet.absoluteFill, styles.maybeRenderUploading]}>
<ActivityIndicator color="#fff" size="large" />
</View>
);
}
};
_maybeRenderImage = () => {
let {
image
} = this.state;
if (!image) {
return;
}
return (
<View
style={styles.maybeRenderContainer}>
<View
style={styles.maybeRenderImageContainer}>
<Image source={{ uri: image }} style={styles.maybeRenderImage} />
</View>
<Text
onPress={this._copyToClipboard}
onLongPress={this._share}
style={styles.maybeRenderImageText}>
{image}
</Text>
</View>
);
};
_share = () => {
Share.share({
message: this.state.image,
title: 'Check out this photo',
url: this.state.image,
});
};
_copyToClipboard = () => {
Clipboard.setString(this.state.image);
alert('Copied image URL to clipboard');
};
_takePhoto = async () => {
const {
status: cameraPerm
} = await Permissions.askAsync(Permissions.CAMERA);
const {
status: cameraRollPerm
} = await Permissions.askAsync(Permissions.CAMERA_ROLL);
// only if user allows permission to camera AND camera roll
if (cameraPerm === 'granted' && cameraRollPerm === 'granted') {
let pickerResult = await ImagePicker.launchCameraAsync({
allowsEditing: true,
aspect: [4, 3],
});
this._handleImagePicked(pickerResult);
}
};
_pickImage = async () => {
const {
status: cameraRollPerm
} = await Permissions.askAsync(Permissions.CAMERA_ROLL);
// only if user allows permission to camera roll
if (cameraRollPerm === 'granted') {
let pickerResult = await ImagePicker.launchImageLibraryAsync({
allowsEditing: true,
aspect: [4, 3],
});
this._handleImagePicked(pickerResult);
}
};
_handleImagePicked = async pickerResult => {
let uploadResponse, uploadResult;
try {
this.setState({
uploading: true
});
if (!pickerResult.cancelled) {
uploadResponse = await uploadImageAsync(pickerResult.uri);
uploadResult = await uploadResponse.json();
this.setState({
image: uploadResult.location
});
}
} catch (e) {
console.log({ uploadResponse });
console.log({ uploadResult });
console.log({ e });
alert('Upload failed, sorry :(');
} finally {
this.setState({
uploading: false
});
}
};
}
async function uploadImageAsync(uri) {
let apiUrl = 'http://192.168.0.18/upload-api/uploading.php';
let uriParts = uri.split('.');
let fileType = uriParts[uriParts.length - 1];
let formData = new FormData();
formData.append('fileToUpload', {
uri,
name: `fileToUpload.${fileType}`,
type: `image/${fileType}`,
});
let options = {
method: 'POST',
body: formData,
headers: {
Accept: 'application/json',
'Content-Type': 'multipart/form-data',
},
};
return fetch(apiUrl, options);
}
and here is my PHP
<?php
$target_dir = 'uploads/';
$target_file = $target_dir . basename($_FILES['fileToUpload']['name']);
$status = array();
if (move_uploaded_file($_FILES['fileToUpload']['tmp_name'], $target_file)) {
$status['status']=1;
$status['description']='upload success';
} else {
$status['status']=0;
$status['description']='upload failed';
}
echo json_encode($status);
?>
Any solution to this? thank you
You can use Fetch Api to upload image
var photo = {
uri: selectImg.localUri,
type: 'image/jpeg',
name: 'photo.jpg',
};
var form = new FormData();
form.append("ProfilePicture", photo);
fetch(
Constants.API_USER + 'me/profilePicture',
{
body: form,
method: "PUT",
headers: {
'Content-Type': 'multipart/form-data',
'Authorization': 'Bearer ' + user.token
}
}
).then((response) => response.json())
.catch((error) => {
alert("ERROR " + error)
})
.then((responseData) => {
alert("Succes "+ responseData)
}).done();
I'am trying to upload a file to the server by using a service which passes the file to the php backend.
It works, but only once. If I try to repeat uploading another file (without reloading the page) it does not get send and this error occurs:
ERROR TypeError: "this.fileManagerService.uploadFile is not a function"
playground.component.html
<form [formGroup]="form" (ngSubmit)="onSubmit()">
<input type="file" name="avatar" (change)="onFileSelect($event)" />
<button type="submit">Upload</button>
</form>
playground.component.ts
export class PlaygroundComponent implements OnInit {
form: FormGroup;
fileManagerResponse;
constructor(private formBuilder: FormBuilder, private fileManagerService: FileManagerService) { }
ngOnInit() {
this.form = this.formBuilder.group({
avatar: ['']
});
}
onFileSelect(event) {
if (event.target.files.length > 0) {
const file = event.target.files[0];
this.form.get('avatar').setValue(file);
}
}
onSubmit() {
const formData = new FormData();
formData.append('avatar', this.form.get('avatar').value);
this.fileManagerService.uploadFile(formData).subscribe(
(res) => {
this.fileManagerService = res;
console.log(res);
},
(err) => {
console.log(err);
}
);
}
}
FileManagerService.ts
export class FileManagerService {
SERVER_URL: string = "http://127.0.0.1/backend/api/";
constructor(private httpClient: HttpClient) { }
public uploadFile(data) {
let uploadURL = `${this.SERVER_URL}/filemanager/upload.php`;
return this.httpClient.post<any>(uploadURL, data);
}
}
The error occurred in below line.
this.fileManagerService = res;
You cannot assign res to the instance of the FileManagerService.
Remove it. Everything will be fine.
I have a problem with my ionic app.
I want to upload an image to my php server when i click on a button but it seems that i am doing something wrong...
Communication.html
<ion-header>
<ion-navbar>
<ion-title>
Ionic3 Server Send Test
</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<ion-list>
<ion-item>
<button ion-button (click)="uploadFile()">Upload</button>
</ion-item>
</ion-list>
</ion-content>
Communication.ts
import { Component } from '#angular/core';
import { NavController } from 'ionic-angular';
import { HttpClient } from '#angular/common/http';
import { FileTransfer, FileUploadOptions, FileTransferObject } from '#ionic-native/file-transfer';
#Component({
selector: 'communication',
templateUrl: 'communication.html'
})
export class CommunicationPage {
imageURI:any;
imageFileName:any;
constructor(public navCtrl: NavController,
private transfer: FileTransfer) {}
uploadFile() {
const fileTransfer: FileTransferObject = this.transfer.create();
let options: FileUploadOptions = {
fileKey: 'ionicfile',
fileName: 'ionicfile',
chunkedMode: false,
headers: {}
}
fileTransfer.upload('C:/Users/Nathan/Desktop/Recognize/src/pages/communication/test.png', 'http://someserver', options)
.then((data) => {
console.log(data+" Uploaded Successfully");
}, (err) => {
console.log(err);
});
}
}
I have this error when i click on the upload button :
FileTransferError {code: 1, source:"C:/Users/Nathan/Desktop/Recognize/src/pages/communication/test.png", target: "http://someserver", http_status: null, body: null, …}
I know there is a problem with the url of the "test.png" file because of code 1 error.
Do you have any idea ?
You need to add image targetPath in fileTransfer.upload() like this,
var targetPath = this.file.dataDirectory + imgName;
fileTransfer.upload(targetPath, 'http://someserver', options)
.then((data) => {
console.log(data+" Uploaded Successfully");
}, (err) => {
console.log(err);
});
Hey Nathan the problem you are having is because of the URL of file, here you are giving the url only test.png.
Rather than you should use FileChooser plugin for cordova which gives the absolute URL of the file.
import { FileChooser } from '#ionic-native/file-chooser';
constructor(private fileChooser: FileChooser) { }
function() {
const fileTransfer: FileTransferObject = this.transfer.create();
let options: FileUploadOptions = {
fileKey: 'ionicfile',
fileName: 'ionicfile',
chunkedMode: false,
headers: {}
}
this.fileChooser.open()
.then(uri => {
fileTransfer.upload(uri, 'http://someserver', options)
.then((data) => {
console.log(data+" Uploaded Successfully");
}, (err) => {
console.log(err);
});
})
.catch(e => console.log(e));
}
Comment down if you want some more help.