I am using the following HTML & PHP code to move multiple images to my server.
Is there a way using my code that I can associate a specific input element with the uploaded file?
So in my for loop, I can discover when the image from 'image_22' is being processed. Is this possible using my current code?
Dream world would be storing the value "image_22" inside a variable $imageNum :-)
Here is a snippet of what I'm currently working with...
HTML:
<input id="image_22" name="images[]" type="file" />
<input id="image_8" name="images[]" type="file" />
...
PHP:
<?php
if (isset($_POST['Submit'])) {
$number_of_file_fields = 0;
$number_of_uploaded_files = 0;
$number_of_moved_files = 0;
$uploaded_files = array();
$upload_directory = dirname(__file__) . '/uploaded/'; //set upload directory
/**
* we get a $_FILES['images'] array ,
* we procee this array while iterating with simple for loop
* you can check this array by print_r($_FILES['images']);
*/
for ($i = 0; $i < count($_FILES['images']['name']); $i++) {
$number_of_file_fields++;
if ($_FILES['images']['name'][$i] != '') { //check if file field empty or not
$number_of_uploaded_files++;
$uploaded_files[] = $_FILES['images']['name'][$i];
if (move_uploaded_file($_FILES['images']['tmp_name'][$i], $upload_directory .
$_FILES['images']['name'][$i])) {
$number_of_moved_files++;
}
}
}
echo "Number of File fields created $number_of_file_fields.<br/> ";
echo "Number of files submitted $number_of_uploaded_files . <br/>";
echo "Number of successfully moved files $number_of_moved_files . <br/>";
echo "File Names are <br/>" . implode(',', $uploaded_files);
}
?>
Thank you!!
In your HTML, just include that value inside the [].
<input id="image_22" name="images[22]" type="file" />
<input id="image_8" name="images[8]" type="file" />
In your loop, instead of an incremental for loop, use a foreach with index, which is a more common pattern in PHP than the incremental type. The $index will be the number supplied in the []:
// Loop over the ['name'] key in $_FILES['images'] to get all the named indexes
foreach ($_FILES['images']['name'] as $index => $filename) {
if ($filename != '') {
// not empty...
$number_of_uploaded_files++;
// Check for validity (see below)...
// Use the name concatenated with _$index to supply store the index with the filename
$uploaded_files[] = $filename . "_$index";
if (move_uploaded_file($_FILES['images']['tmp_name'][$index], $upload_directory . $filename . "_$index")) {
// successful rename
$number_of_moved_files++;
}
}
}
Note that your script is currently vulnerable to path injection attacks. You must filter the name of each file against the inclusion of things like ../ which could force the file to be saved anywhere on your filesystem (writable by the web server)! It is recommended to check the name with a regular expression of acceptable values:
// Verify that the uploaded filename contains only letters, numbers, hyphen, underscore, space before the `.` and letters only after the `.`
// You could also insist that it end in `.(jpg|gif|png)` or whatever your acceptable formats are
// Most important is to prevent things like `../`
if (preg_match('/^[a-z0-9_- ]+\.[a-z]+$/i', $filename)) {
// It's an ok filename
}
Related
I'm trying to get my image uploader to handle multiple files.
In my HTML I have added the array brackets to the name attribute and added the multiple attribute:
HTML
<input id="standard-upload-files" type="file" name="standard-upload-files[]" multiple>
PHP
I've reduced the code down, but the images aren't being processed and I'm getting the error message that displays in the else part of the code.
Any help as to why the files aren't being processed would be hugely appreciated.
if(isset($_POST['submit-images'])) {
$profileImage = $_POST['submit-images'];
foreach($_FILES['standard-upload-files']['name'] as $filename) {
if($_FILES['standard-upload-files']['error'] === 0 ) {
$temp = $_FILES['standard-upload-files']['tmp_name'];
// set base time and ID for all images before loop
$filebase = uniqid() . '_' . time();
// FULL SIZE IMAGE THAT WILL BE DOWNLOADED BY USERS
move_uploaded_file($temp, "images-download/{$filebase}");
} else {
$error[] = "Image failed to load please try again";
}
} // foreach
}
I downloaded this upload example: https://github.com/xmissra/UploadiFive
When sending an apernas file, it works perfectly but when sending more than one file the function that checks if the file already exists presents a problem. Apparently the loop does not ignore that the file has just been sent and presents the message asking to replace the file. Is there any way to solve this?
This is the function that checks if the file already exists.
$targetFolder = 'uploads'; // Relative to the root and should match the upload folder in the uploader
script
if (file_exists($targetFolder . '/' . $_POST['filename'])) {
echo 1;
} else {
echo 0;
}
You can test the upload working at: http://inside.epizy.com/index.php
*Submit a file and then send more than one to test.
I tried it this way but it didn't work:
$targetFolder = 'uploads';
$files = array($_POST['filename']);
foreach($files as $file){
if (file_exists($targetFolder . '/' . $file)) {
echo 1;
} else {
echo 0;
}
When you have multiple files to be uploaded keep these things in mind;
HTML
Input name must be array name="file[]"
Include multiple keyword inside input tag.
eg; <input name="files[]" type="file" multiple="multiple" />
PHP
Use syntax $_FILES['inputName']['parameter'][index]
Look for empty files using array_filter()
$filesCount = count($_FILES['upload']['name']);
// Loop through each file
for ($i = 0; $i < $filesCount; $i++) {
// $files = array_filter($_FILES['upload']['name']); use if required
if (file_exists($targetFolder . '/' . $_FILES['upload']['name'][$i])) {
echo 1;
} else {
echo 0;
}
}
How do I upload an images and then save with a different name and multiple copies in the same directory ?
One copy of the uploaded image(abcd.jpg) needs to be named '212_1_today_00.jpg' and another copy needs be named '424_1_today_00.jpg' and may be another '848_1_today_01.jpg'
better use time() instead of today as random no might be repeated at some point.......
<?php
if($_FILES){
$image = $_FILES['image'];
if($image['error'] == 0){
$a = explode('.',$image['name']);
$e = end($a);
$t = time();
$name = rand(100, 999)."_1_{$t}";
move_uploaded_file($image['tmp_name'], $name.'_00.'.$e);
# if u want 1 copy
copy($name.'_00.'.$e, rand(100, 999)."_1_{$t}_01.{$e}");
# if u want n more copies
/*
$n = 5; #no of copies u want
for ($i = 1; $i <= $n; $i++) {
copy($name.'_00.'.$e, rand(100, 999)."_1_{$t}_0{$i}.{$e}");
}
*/
echo 'Done';
}
}
?>
<form method="post" enctype="multipart/form-data">
<input type="file" name="image" accept='image/*'/>
<input type="submit">
</form>
First I uploaded one with the name '212_1_today_00.jpg' and I copied using PHP function - copy
Found at http://www.php.net/manual/en/function.copy.php
<?php
$file = './myfolder/212_1_today_00.jpg';
$newfile = './myfolder/424_1_today_00.jpg';
if (!copy($file, $newfile)) {
echo "failed to copy $file...\n";
}
I have a form that uploads multiple file. The php code that I am using works fine but I would like to rename the files also and don't know how to go about this. I think adding a time stamp to the name would be the best answer. Here is the working code so far:
/* FILE UPLOAD CODE */
{
$number_of_file_fields = 0;
$number_of_uploaded_files = 0;
$number_of_moved_files = 0;
$uploaded_files = array();
$upload_directory = dirname(__file__) . '/uploads/'; //set upload directory
/**
* we get a $_FILES['file'] array ,
* we procee this array while iterating with simple for loop
* you can check this array by print_r($_FILES['file']);
*/
for ($i = 0; $i < count($_FILES['file']['name']); $i++) {
$number_of_file_fields++;
if ($_FILES['file']['name'][$i] != '') { //check if file field empty or not
$number_of_uploaded_files++;
$uploaded_files[] = $_FILES['file']['name'][$i];
if (move_uploaded_file($_FILES['file']['tmp_name'][$i], $upload_directory . $_FILES['file']['name'][$i])) {
$number_of_moved_files++;
}
}
}
}
/* END FILE UPLOAD CODE */
Any help on what to add and where to accomplish this would be greatly appreciated.
If you want to give the same name to all the uploaded files, then you can get the name by using $_GET.
For example:
<form action="upload.php" method="post"> \\ this would send it to your page
<input type='text' size='30' name='filename'/>
<input type='submit' />
</form>
simply get the name using $_GET like this
$name = $_GET['filename'];
and now run your code but move the file with this name like this
move_uploaded_file($_FILES['file']['tmp_name'][$i], $upload_directory . $name[$i])
You can specify the new file name as the second parameter in move_uploaded_file()
For example:
move_uploaded_file($_FILES['file']['tmp_name'][$i], $upload_directory . "new_file_name");
The purpose of the script is to change the names of of a list of images within a directory for an ecommerce site. So specifically when the script is rand a user will type in a word or phrase that they would like a set or list of files to be prefixed with. The script will iterate over each file changing the prefix and appending the next available number starting from zero.
I'd like to display/render on the page to the user what files have been changed. right now when the script is ran it displays the current files within the directory, and then it list the changed files and their names within the directory.
How can i get the file list only to display when the script has finish processing the new names?
Why does the script not append the proper incremented number to the file name? It renames files the following order:
abc0.jpg
abc1.jpg
abc10.jpg
abc11.jpg
abc12.jpg
abc13.jpg
<?php
$display_file_list;
//Allow user to put choose name
if (isset($_POST['file_prefix'])){
$the_user_prefix = $_POST['file_prefix'];
//open the current directory change this to modify where you are looking
$dir = opendir('.');
$i=0;
//Loop though all the files in the directory
while(false !==($file = readdir($dir)))
{
//This is the way we would like the page to function
//if the extention is .jpg
if(strtolower(pathinfo($file, PATHINFO_EXTENSION)) =='jpg')
{
//Put the JPG files in an array to display to the user
$display_file_list[]= $file;
//Do the rename based on the current iteration
$newName = $the_user_prefix.$i . '.jpg';
rename($file, $newName);
//increase for the next loop
$i++;
}
}
//close the directory handle
closedir($dir);
}else{
echo "No file prefix provided";
}
?>
<html>
<body>
<form action="<?=$_SERVER['PHP_SELF']?>" method="POST">
<input type="text" name="file_prefix"><br>
<input type="submit" value="submit" name="submitMe">
</form>
</body>
</html>
<?php
foreach ($display_file_list as $key => $value) {
echo $value. "<br>";
}
?>
"How can i get the file list only to display when the script has finish processing the new names?"
I think this will work for you;
$path = "path/to/files";
$files = glob("{$path}/*.jpg");
$files_renamed = array();
foreach ($files as $i => $file) {
$name = "{$path}/{$prefix}{$i}.jpg";
if (true === rename($file)) {
$files_renamed[] = $name;
}
}
print_r($files_renamed);