Reputation: 2478
I created a very basic example of a multiple file upload form (reference), it works perfect on desktop but not on mobile, at least the ones I am testing with.
On Mobile (Xiaomi Mi4 [Android version: 6.1] - Google Chrome/Mozilla Firefox): When I click on Choose files I see this screen:
If I choose Google Photos and select multiple files, only the first file will be inserted into the form. If I select the Gallery (native) app and select multiple files I get the correct number on the form but when I click upload I get the "Aw Snap" screen:
Any idea why this is happening?
Besides Google Photos and the native app I tried 5 different apps, the last one, Piktures actually worked!
Please tell me this is not an app thing... is there a way to get the files correctly?
Code attached:
<form method="post" enctype="multipart/form-data">
<input type="file" name="my_file[]" multiple>
<input type="submit" value="Upload">
</form>
<?php
if (isset($_FILES['my_file'])) {
$myFile = $_FILES['my_file'];
$fileCount = count($myFile["name"]);
for ($i = 0; $i < $fileCount; $i++) {
?>
<p>File #<?= $i+1 ?>:</p>
<p>
Name: <?= $myFile["name"][$i] ?><br>
Temporary file: <?= $myFile["tmp_name"][$i] ?><br>
Type: <?= $myFile["type"][$i] ?><br>
Size: <?= $myFile["size"][$i] ?><br>
Error: <?= $myFile["error"][$i] ?><br>
</p>
<?php
}
}
?>
If you wish to test: http://odedta.com/projects/jqueryfileupload/
Thanks!
Upvotes: 12
Views: 13495
Reputation: 797
I am not sure exactly about that mobile browsers are support multiple
attribute I read some article it is not support or is not standart, any way If you want to post multiple image; You can see full code below
First Step;
You should use FileReader
for load on browser as locally
Multiple file loading with FileReader
document.getElementById("filesToUpload").onchange = function () {
var fileIndex = 0;
for ( var x= 0; x < input.files.length; x++) {
//add to list
var li = document.createElement('li');
//Filename listing
li.setAttribute('id','li_'+x);
li.innerHTML = 'File ' + (x + 1) + ': ' + input.files[x].name;
list.append(li);
//FileReader create and set onload event
var reader = new FileReader();
reader.onload = function (data) {
data.target.result;
}
//Read file
reader.readAsDataURL(input.files[x]);
}
}
Second Step
You can set image content to textarea as base64 data for each file
reader.onload = function (data) {
//....
//Split base64 data from DataURL (// "data:image/png;base64,.....)
var b64 = data.target.result.split(',')[1];
var b64Input = document.createElement('textarea');
b64Input.setAttribute('name','file64[]');
b64Input.value = b64;
//...
}
Third Step
Then you can send to your php file whole data and save your content as image
for($i = 0; $i<count($_POST["fileName"]);$i++){
echo $_POST["fileName"][$i]."<br>";
//decode base64 content and put file
file_put_contents($_POST["fileName"][$i], base64_decode($_POST["file64"][$i]));
}
Full Code
HTML & JavaScript
<input name="filesToUpload[]" id="filesToUpload" type="file" multiple />
<form method="post" action="multipleFileUpload.php" enctype="multipart/form-data" id="formMultipleFileUpload">
<ul id="fileList">
</ul>
<input type="submit" value="Upload" id="btnUpload">
</form>
<script type="text/javascript">
var input = document.getElementById('filesToUpload');
var list = document.getElementById('fileList');
document.getElementById("filesToUpload").onchange = function () {
var fileIndex = 0;
for ( var x= 0; x < input.files.length; x++) {
//add to list
var li = document.createElement('li');
li.setAttribute('id','li_'+x);
li.innerHTML = 'File ' + (x + 1) + ': ' + input.files[x].name;
list.append(li);
var reader = new FileReader();
reader.onload = function (data) {
var li = document.getElementById('li_'+fileIndex);
var previewImg = document.createElement('img');
previewImg.setAttribute('width','50');
previewImg.setAttribute('height','50');
li.append(previewImg);
previewImg.src = data.target.result;
var b64 = data.target.result.split(',')[1];
var b64Input = document.createElement('textarea');
b64Input.setAttribute('name','file64[]');
b64Input.value = b64;
li.append(b64Input);
var fileName = document.createElement('input');
fileName.setAttribute('name','fileName[]');
fileName.value = input.files[fileIndex].name;
li.append(fileName);
fileIndex++;
}
reader.readAsDataURL(input.files[x]);
}
}
PHP (multipleFileUpload.php)
<?php
for($i = 0; $i<count($_POST["fileName"]);$i++){
echo $_POST["fileName"][$i]."<br>";
file_put_contents($_POST["fileName"][$i], base64_decode($_POST["file64"][$i]));
}
?>
Upvotes: 2
Reputation: 7591
Try this might help you this is only front end part of file upload with js
window.onload = function() {
if (window.File && window.FileList && window.FileReader) {
var filesInput = document.getElementById("uploadImage");
filesInput.addEventListener("change", function(event) {
var files = event.target.files;
var output = document.getElementById("result");
for (var i = 0; i < files.length; i++) {
var file = files[i];
if (!file.type.match('image'))
continue;
var picReader = new FileReader();
picReader.addEventListener("load", function(event) {
var picFile = event.target;
var div = document.createElement("div");
div.innerHTML = "<img class='thumbnail' src='" + picFile.result + "'" +
"title='" + picFile.name + "'/>";
output.insertBefore(div, null);
});
picReader.readAsDataURL(file);
}
});
}
}
<input type="file" id="uploadImage" name="termek_file" class="file_input" multiple/>
<div id="result" class="uploadPreview">
Upvotes: 8