php - naming Multiple file input fields on a form - php

I am wanting to have multiple fields on one form that can insert files.
I have the below script, but I want to be able to identify what field the inserted file belongs to in the saved name.
<form action="" method="post" enctype='multipart/form-data' id="form" name="form">
Input 1<input type="file" name="upload[]" >
Input 2<input type="file" name="upload[]" >
Input 3<input type="file" name="upload[]" >
<button id="submit-button">Upload</button>
</form>
<?php
//if(isset($_POST['submit']) && !empty($_POST) ){
$count = 0;
$max_file_size = 5000000;
if(isset($_POST) and $_SERVER['REQUEST_METHOD'] == "POST"){
// Loop $_FILES to exeicute all files
foreach ($_FILES['upload']['name'] as $f => $name) {
$path = 'documents'; //path of directory
if ($_FILES['upload']['error'][$f] == 4) {
continue; // Skip file if any error found
} else {
if ($_FILES['upload']['size'][$f] > $max_file_size) {
$message[] = "$name is too large!.";
continue; // Skip large files
}
else {
// No error found! Move uploaded files
//$name_of_file = $_FILES['username']['name'][$f];
$temp_name = $_FILES['upload']['tmp_name'][$f]; //[$count];
move_uploaded_file($temp_name, "$path/"."$name");
$count++; // Number of successfully uploaded file
}
}
}
}
At the moment it just saves the files into the one location, so I cant differentiate them and identify which field they are from.
can anyone please help?

I have worked it out. I have taken the comments above and placed an Text input field at each of the File Fields. These could also be hidden fields if you need set names.
Then I scroll through them and save the names and apply those names on the server side.
Thanks to the comments, they helped me see the solution.
<form action="" method="post" enctype='multipart/form-data' id="form" name="form">
<input type="text" name="input0" value=""><input type="file" name="upload[]" ><br><br>
<input type="text" name="input1" value=""><input type="file" name="upload[]" ><br><br>
<input type="text" name="input2" value=""><input type="file" name="upload[]" ><br><br>
<button id="submit-button">Upload</button>
</form>
<?php
$count = 0;
$max_file_size = 500000000000;
if(isset($_POST) and $_SERVER['REQUEST_METHOD'] == "POST"){
// Loop $_FILES to exeicute all files
$x = 0;
$input = "input";
while ($x <= 2){
$field_name = $input.$x;
$field[$x] = $_POST[$field_name];
$x++;
}
foreach ($_FILES['upload']['name'] as $f => $name) {
$path = 'documents'; //path of directory
if ($_FILES['upload']['error'][$f] == 4) {
continue; // Skip file if any error found
} else {
if ($_FILES['upload']['size'][$f] > $max_file_size) {
$message[] = "$name is too large!.";
continue; // Skip large files
}
else {
$temp_name = $_FILES['upload']['tmp_name'][$f]; //[$count];
move_uploaded_file($temp_name, "$path/"."$field[$count]"."$name");
$count++; // Number of successfully uploaded file
}
}
}
}

Related

Match indexes of two arrays in PHP to pair data

I am doing a form with multiple files upload, for each file input there is a title input and I want to match the title with the file in order to be able to rename the file with the title.
I don't know how to match indexes of the two arrays to be able to do this.
Could someone help me? Thx
Here is my code so far ...
PHP :
$target_dir = 'files/';
if(isset($_POST['title']) && !empty($_POST['title'])){
$total_titles = count($_POST['title']);
for($key = 0; $key < $total_titles; $key++) {
// Clean retrieved client data
$pageName= $_POST['titles'];
}
// Check files
if(isset($_FILES['userfile']['name'])) {
// Count the number of uploaded files
$total_files = count($_FILES['userfile']['name']);
// Loop on uploaded files
for($key = 0; $key < $total_files; $key++) {
// Check if file is selected
if(isset($_FILES['userfile']['name'][$key]) && $_FILES['userfile']['size'][$key] > 0) {
$original_filename = $_FILES['userfile']['name'][$key];
// Get the file extension
$extension = pathinfo($original_filename, PATHINFO_EXTENSION);
// Get filename without extension
$filename_without_extension = basename($original_filename, '.'.$extension);
// Generate new filename
$new_filename = str_replace(' ', '_', $filename_without_extension) . '_' . '.' . $extension;
// Upload the file with new name
move_uploaded_file($_FILES['userfile']['tmp_name'][$key], $target_dir . $new_filename);
}
}
}
}
HTML
<div class="container">
<div class="row justify-content-center">
<!-- Page names -->
<form class="form col-xl-6" action="" id="page_list_section" method="post" enctype="multipart/form-data">
<input type="text" name="title[]" placeholder="Title" >
<input type="file" name="userfile[]" >
<input type="text" name="title[]" placeholder="Title" >
<input type="file" name="userfile[]" >
<input type="submit" name="Submit" value="Upload" >
</form>
</div>
</div>
Here is the match:
for($key = 0; $key < $total_files; $key++) {
$title = $_POST['title'][$key];
$filename = $_FILES['userfile']['name'][$key];
}

PHP - Frequent error on multiple images upload

I created a multiple image upload form (the images are stored in a folder, and the informations in a MySQL database). To the images are associated some informations, like a description, a name, etc.
Often, when I upload many images (like 3,4), one/two of them aren't uploaded, and an error message appears (An error has occurred while uploading the file). Then, if I retry to upload the image not uploaded, no error occurs. Sometimes it appends, sometimes not, and I don't understand what the problem is (I think it is not normal).
Here you can see my PHP code and also my HTML form:
When the user clicks on the input type="file", my code just creates another input and hides the old one (so that, if the user wants upload more files, those already uploaded are not deleted).
function boomFunction(obj) {
obj.style.display = 'none';
$(".upload-container").append("<input name='upload[]' type='file' multiple='multiple' id='upload' class='upload' onclick='boomFunction(this)' title='Carica un altro file!'>");
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form action="result.php" method="post" enctype="multipart/form-data" class="form-inline" autocomplete="off" novalidate>
<div class="upload-container">
<input name="upload[]" type="file" multiple="multiple" id="upload" class="upload" required="required" aria-required="true" onclick="boomFunction(this)" title="Choose a file!">
</div><br>
<label>Subjects:</label>
<textarea type="text" id="argomenti" name="argomenti" required="required" aria-required="true" placeholder="Subjects..."></textarea><br>
<label for="anno">Year:</label>
<select id="anno" name="anno" required="required" aria-required="true">
<option value="" disabled selected>Choose year</option>
<option value="2016-2017">2016-2017</option>
<option value="2017-2018">2017-2018</option>
<option value="2018-2019">2018-2019</option>
</select><br>
<input type="submit" value="Carica i file" class="upload_button"><br><br><br>
</form>
Then, here is my result.php page.
<?php
$total = count(array_filter($_FILES['upload']['name'])); // Count the number of uploaded files
$timestamp = time();
if ($total==0) {
echo "<h2>You must upload at least one file.</h2>";
$uploadOk = 0;
} else {
for($i = 0; $i < $total; $i++) {
$tmpFilePath = $_FILES['upload']['tmp_name'][$i];
if ($tmpFilePath != '') {
$newFilePath = "./uploadFiles/" . $_FILES['upload']['name'][$i];
$nomeCompletoFile = basename($_FILES["upload"]["name"][$i]);
$target_file = "uploads/$nomeCompletoFile"; $uploadOk = 1;
$estensione = strtolower(pathinfo($target_file, PATHINFO_EXTENSION));
if($estensione != 'jpg' && $estensione != 'png' && $estensione != 'jpeg') {
echo "<h2>Just JPG e PNG files are allowed.</h2>";
$uploadOk = 0;
}
elseif (empty($_POST["argomenti"]) or empty($_POST["anno"])) {
echo "<h2>You cannot leave empty fields</h2>";
$uploadOk = 0;
} else {
$nomeFile = str_replace(".$estensione", '', $nomeCompletoFile);
$string = base64_encode(openssl_random_pseudo_bytes(15)); // Random 15 letters for the new file name
$id = rand(1, 100000); $nomeFinaleFile = 'uploads/'.$string.$id.'.'.$estensione;
if (move_uploaded_file($_FILES["upload"]["tmp_name"][$i], $nomeFinaleFile)) {
$argomenti = stripslashes(htmlspecialchars($_POST['argomenti']));
$anno = $_POST['anno'];
$mysqli = new mysqli('localhost', 'name', '', 'my_name');
$mysqli->query("INSERT INTO uploads (timestamp, file, argomenti, anno, nFile) VALUES ('$timestamp', '$nomeFinaleFile', '$argomenti', '$anno', '$i')");
echo "<h2>The file <i>$nomeFile</i> has been uploaded.</h2>";
} else echo "<h2>An error has occurred while uploading the file</h2>";
}
}
}
}
?>
There seems to be no mistakes, indeed sometimes all works correctly.
Any help will be appreciated
Use base64encode url safe
replace
$string = base64_encode(openssl_random_pseudo_bytes(15)); // Random 15 letters for the new file name
to
$string = rtrim(strtr(base64_encode(openssl_random_pseudo_bytes(15)), ['+' => '-', '/' => '_']), '=');

How to upload an array of files?

I'm trying to build an array of files by submitting a form several times, then move those files to a directory, but it's not working. Every uploads just overrides the previous and then it doesn't even move that one (the upload_to_file() function doesn't do anything)
HTML:
<form id="form" action="home.php" method="post" enctype="multipart/form-data">
<input type="hidden" name="MAX_FILE_SIZE" value="8000000">
<input class="upload_btn" type="file" name="images[]" id="image_file">
<input type="submit" id="img_submit" class="form_button" name="submit_image" value="upload"/>
</form>
It is important that there is only one upload button which can be used to upload many files.
I need them to be stored in an array so I can display their ['name'] anywhere with a loop.for ($i = 0; $i < count($_FILES['images']['name']); $i++){}
Then once another form is submitted it calls a function to move each file in the array to a directory.
Function inside an included php file:
function upload_to_file(){
$image_paths = array();
$target_dir = "uploads/images/";
$path = $target_dir . basename($_FILES['images']['name'][0]);
if(isset($_FILES['images']['name'][0]) && $_FILES['images']['size'][0] > 0)
{
if (move_uploaded_file($_FILES['images']['tmp_name'][0], $path)) {
$image_paths[0] = "uploads/images/";
}
}
return $image_paths;
}
I'm only testing it with the first element in the array, but will need to make a loop later.
Here is the program, which help you to upload multiple files. in the code "sub" is the submit button name. "upload" is the name of file controller, the uploaded files are stored in the directory called "img" that you have to create on your root folder.
<?php
if (isset($_POST['sub'])) {
if (count($_FILES['upload']['name']) > 0) {
for ($i=0; $i<count($_FILES['upload']['name']); $i++) {
$tmpFilePath = $_FILES['upload']['tmp_name'][$i];
if ($tmpFilePath != "") {
$shortname = $_FILES['upload']['name'][$i];
$filePath = "img/" . date('d-m-Y-H-i-s').'-'.$_FILES['upload']['name'][$i];
if (move_uploaded_file($tmpFilePath, $filePath)) {
$files[] = $shortname;
}
}
}
}
echo "<h1>Uploaded:</h1>";
if(is_array($files)){
echo "<ul>";
foreach($files as $file){
echo "<li>$file</li>";
}
echo "</ul>";
}
}
?>
HTML Code is given
<form action="" enctype="multipart/form-data" method="post">
<input id='upload' name="upload[]" type="file" multiple="multiple" />
<input type="submit" name="sub" value="Upload Now">
</form>

PHP Upload with file type and size check

I need a upload form which other people can use, to hand me in their documents.
HTML:
<form method="post" action="upload.php" enctype="multipart/form-data" id="form">
<table>
<tr><td><p>your name:</p></td></tr>
<tr><td><input name="name" type="text" size="50" style="height: 30px;"></td></tr>
<tr><td><p>your mail-adress:</p></td></tr>
<tr><td><input name="mail" type="text" size="50" style="height: 30px;"></td></tr>
<tr><td><p>your document:</p></td></tr>
<tr><td><input type="file" name="file" value="" /><br /><h6 style="margin-top: 5px; margin-bottom: 2px;">max. filesize: 2 MB<br />allowed filetypes: .doc, .docx, .pdf, .rtf, .odt</h6></td></tr>
</table>
<br />
<input type="submit" value="Send">
</form>
PHP:
<?php
$fehler = "";
$name = $_POST['name'];
$mail = $_POST['mail'];
$file = $_POST['file'];
$maxsize = "2097152"; /* 2MB in Bytes */
$allowedext = array('doc','docx' ,'pdf', 'rtf', 'odt');
if (empty($name)) {
$fehler .= "<p>• no name given!</p>" ;
}
if (empty($mail)) {
$error .= "<p>• no e-mail adress given</p>" ;
}
if (empty($file)) {
$error .= "<p>• choose a file!</p>" ;
}
if (empty($error)) {
if (!in_array(filetype($file), $allowedext) { /* check filetype */
$error .= "<p>• filetype is not allowed</p>" ;
}
if (empty($error)) {
if (filesize($file) > $maxsize) { /* check filesize */
$error .= "<p>• file is too big</p>" ;
}
if (empty($error)) {
/* send data via mail */
echo("your document has been send.");
}
}
}
echo($error);
echo ('<p>back</p>');
?>
I want to check the file type and the size before uploading it. When I upload the upload.php file to my server i just get a white screen without any errors, if i try to use this form.
Change your $_POST['file'] to $_FILES['file']
and try:
// check maximum size
if($_FILES['file']['size'] > $maxsize)
die('The file is too large');
// check file format
elseif( !in_array(pathinfo(strtolower($_FILES['files']['name']), PATHINFO_EXTENSION),$allowedex))
die($_FILES['files']['name'].' is not a valid format.');
This answer provides the solution to check size before uploading to data to the server. This makes sense. If you do a client check, you can eliminate unnecessary posts to your server. A sanity check on the server remains necessary, JavaScript code on the client can be altered. The other answers provide explanation on how to improve your server side code.
var mimeTypes = [
"application/vnd.openxmlformats-officedocument.wordprocessingml.document", //docx
"application/pdf", //pdf
"application/msword", //doc
"rtf;application/rtf", //rtf
"rtf;application/x-rtf",
"rtf;text/richtext",
"application/vnd.oasis.opendocument.text" //odt
]
function readFiles(files)
{
var iMax = files.length;
var sum = "";
var max = 2097152;
for (var i = 0; i < iMax; i++)
{
var fileType = files[i].type;
var fileSize = files[i].size;
sum += parseInt(fileSize);
if (mimeTypes.indexOf(files[i].type) == -1)
{
alert("Invalid file selected");
return false;
}
}
if (sum > max)
{
alert("Total file size exceeds maximum upload size.");
return false;
}
return true;
}
document.getElementById("form").querySelector("input[type='file']").addEventListener("change", readFiles, false);
readFiles fires whenever a change event is fired on the file input. In browsers supporting HTML5 input elements you can read out the file type and file size property. They are inherited from the Blob object. You can even pass the file to a FileReader object allowing you to read the contents of the file.
Bug in IE 10, 11. On IE10 and 11 there is a bug present that returns an empty string on file-type when used on images. You can work around this by checking the extension.
interesting....i prefer less lines of code...
<form method="post" action="upload.php" enctype="multipart/form-data" id="form">
<table>
<tr><td><p>your name:</p></td></tr>
<tr><td><input required="required" name="name" type="text" size="50" style="height: 30px;"></td></tr>
<tr><td><p>your mail-adress:</p></td></tr>
<tr><td><input required="required" name="mail" type="text" size="50" style="height: 30px;"></td></tr>
<tr><td><p>your document:</p></td></tr>
<tr><td><input required="required" type="file" name="file" value="" /><br /><h6 style="margin-top: 5px; margin-bottom: 2px;">max. filesize: 2 MB<br />allowed filetypes: .doc, .docx, .pdf, .rtf, .odt</h6></td></tr>
</table>
<br />
<input type="submit" value="Send">
</form>
php :
<?php
define('MB', 1048576);
$name = $_POST['name'];
$mail = $_POST['mail'];
$file = $_FILES['file'];
$allowedext = array('doc','docx' ,'pdf', 'rtf', 'odt');
$filename = $file['tmp_name'];
$ext=explode(".",$filename);
if( empty($name) || empty($mail) || empty($file) || $_FILES['file']['size'] > 2*MB || !in_array($ext[1],$allowedext) )
{
echo "check file extension or check whether all fields are filled correctly!";
exit;
}
else
{
move_uploaded_file(name, name);
echo "File has been uploaded successfully!";
}
?>

Upload multiple images to Database MYSQLI

I am planning to have a web gallery. However, it is hard for me to use PHP to insert DB. The following code:
HTML -- I want to make a form which has category and multiple images that can be inserted into DB at the same time.
<form action="upload" method="POST" enctype="multipart/form-data">
<p> Upload : <input type="file" id="file" name="images" /> </p>
<p> Category : <input type="text" name="imageCategory"> </p>
<p> <input type="submit" name="submit" value="Upload!" /> </p>
</form>
DATABASE
I am using imageName as VARCHAR not BLOB TYPE.
PHP
<?php
include ("dbConnect.php");
if(isset($_POST["submit"])) {
$image = $_POST['images']['tmp_name'];
$imageName = $_POST['images']['name'];
$imageSize = $_POST['images']['size'];
$imageType = $_POST['images']['type'];
$imageCategory = $_POST['imageCategory'];
$result = $mysqli->query("INSERT INTO imageTable (imageName, imageCategory, imageSize, imageType)
VALUES ('$imageName', '$imageCategory', '$imageSize' , '$imageType' );")
or die(mysqli_error($mysqli));
} else {
echo "<p> It is not working </p>";
}
header("location: index");
$mysqli->close();
?>
The problem is, the category is the only one has inserted into the database successfully. But not with the imageName, imageType, and imageSize. And also i want the image to be stored into database so that I can retrieve the image from DB on the other web page. Any ideas?
You can use 'multiple' property in the 'input' tag like this :
<form action="file-upload.php" method="post" enctype="multipart/form-data">
Send these files:<br />
<p> <input name="userfile[]" type="file" multiple='multiple' /> </p>
<p> Category : <input type="text" name="imageCategory"> </p>
<input type="submit" value="Send files" />
</form>
User can select multiple files and upload them.
And at the server you will do this :
if (isset($_FILES["userfile"]) && !empty($_FILES["userfile"])) {
$image = $_FILES['userfile']['tmp_name'];
$imageName = $_FILES['userfile']['name'];
$imageSize = $_FILES['userfile']['size'];
$imageType = $_FILES['userfile']['type'];
$imageCategory = $_POST['imageCategory'];
$len = count($image);
$path = "images/";
for ($i = 0; $i < $len; $i++) {
if (isset($imageName[$i]) && $imageName[$i] !== NULL) {
if(move_uploaded_file($image[$i], $path.$imageName[$i])) {
$result = $mysqli->query("INSERT INTO imageTable (imageName, imageCategory, imageSize, imageType) VALUES ('$imageName[$i]', '$imageCategory', '$imageSize[$i]' , '$imageType[$i]' )");
}
}
}
}
$mysqli->close();
header("location: index");
First off the file information won't be in the $_POST global variable it will be in the $_FILES
From http://php.net/manual/en/features.file-upload.multiple.php (modified):
Form
<form action="file-upload.php" method="post" enctype="multipart/form-data">
Send these files:<br />
<p> <input name="userfile[]" type="file" /> </p>
<p> <input name="userfile[]" type="file" /> </p>
<p> Category : <input type="text" name="imageCategory"> </p>
<input type="submit" value="Send files" />
</form>
Parse the global file variable to an array (we'll assume this is a helper function called parseFiles.php):
<?php
function reArrayFiles(&$file_post) {
$file_ary = array();
$file_count = count($file_post['name']);
$file_keys = array_keys($file_post);
for ($i=0; $i<$file_count; $i++) {
foreach ($file_keys as $key) {
$file_ary[$i][$key] = $file_post[$key][$i];
}
}
return $file_ary;
}
Move the files and insert the file information into the database :
<?php
include ("dbConnect.php");
include ("parseFiles.php");
if ($_FILES['upload']) {
$file_ary = reArrayFiles($_FILES['userfile']);
foreach ($file_ary as $file) {
$image = $file['tmp_name'];
$imageName = $file['name'];
$imageSize = $file['size'];
$imageType = $file['type'];
$imageCategory = $_POST['imageCategory'];
$result = $mysqli->query("INSERT INTO imageTable (imageName, imageCategory, imageSize, imageType)
VALUES ('$imageName', '$imageCategory', '$imageSize' , '$imageType' );")
or die(mysqli_error($mysqli));
}
} else {
echo "<p> It is not working </p>";
}
header("location: index");
$mysqli->close();
Hopefully that should do the job. I've not tested this I've just blind coded it so there may be some bugs

Categories