Php uploaded file unique name issue - php

Well, I've a html Upload form which process by .php file (uploader.php). It's a multiple file uploaded code.
So when it's upload, all files are go to upload directory with their individual file name. Like: abc.jpg, abc2.jpg etc.
But If someone upload a file with same name then it's ovrwrite the existing file. So that I need a unique name for the uploaded file. Is there any way to rename the file with unique random name. Like: 12545454.jpge, 234324324.jpge, 323453253.jpg etc..
Php Code:
<?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);
}
?>

Use uniqid() . It is made for this.

You can concat time(); and session_id() or uniqid() as suggested by wormhit is also very good idea against name of each file.
Use The below code:
<?php
$target_path = "images/";
$target_path = $target_path . basename( $_FILES['uploadedfile']['name']);
if(move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) {
echo "The file ". basename( $_FILES['uploadedfile']['name']).
" has been uploaded";
} else{
echo "There was an error uploading the file, please try again!";
}
//$upload_directory = ''.uniqid().'_'.dirname(__file__) . '/uploaded/'; //set upload directory
$uploaded_file="".$upload_directory ."/".uniqid()."_".$_FILES['images']['name'][$i]."";
if (move_uploaded_file($_FILES['images']['tmp_name'][$i],$uploaded_file)) {
$number_of_moved_files++;
}
?>
<?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
$uploaded_file="".$upload_directory ."".uniqid()."_".$_FILES['images']['name'][$i]."";
$number_of_uploaded_files++;
$uploaded_files[] = $_FILES['images']['name'][$i];
if (move_uploaded_file($_FILES['images']['tmp_name'][$i],$uploaded_file)) {
$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);
}
?>

You can use this
$ext = pathinfo($file_name, PATHINFO_EXTENSION);
$newfilename = substr( sha1(uniqid (rand())), 0, 10). '.'.$ext;

Related

PHP read lines not working on some computers but works on most

So im reading an CSV file and splitting it apart to get email,name,last name, however this outputs differently on different computers in my platform, let's say when I upload the same file it reads 38 lines and save them. However in 2 specific computers it reads only 1.
Before I was reading only TEMP file, but now im saving it to a directory and reading from there, however the problem is still here, I compared the file size and is the same even the content.
Is this a PHP bug ?
<?php
global $user;
if(isset($_POST['submit'])) {
if ($_FILES['file']['tmp_name']) {
$nome = $_POST['nome'];
$file = $_FILES['file']['tmp_name'];
$user->criarLista($nome, $file);
} else {
$user->mensagem(1, "Não existe nenhum ficheiro");
}
}
?>
public function criarLista($nome,$file){
// ADDED TO SAVE THE FILE IN THE SYSTEM AND READ FROM IT
if(file_exists("uploads/lista.txt")){ unlink("uploads/lista.txt"); }
move_uploaded_file($file, "uploads/lista.txt");
$file = file_get_contents("uploads/lista.txt");
$user = $this->user;
$get = $this->connect->query("SELECT * FROM users WHERE email = '$user'");
$fetch = $get->fetch_array(MYSQLI_ASSOC);
$user_id = $fetch['id'];
if($insert = $this->connect->prepare("INSERT INTO lista(user_id,nome) VALUES(?,?)")){
$insert->bind_param("is", $user_id,$nome);
$insert->execute();
$list_id = $insert->insert_id;
$file = preg_replace('#\\x1b[[][^A-Za-z]*[A-Za-z]#', '', $file);
$file = strip_tags($file);
$lines = file("uploads/lista.txt");
$emails = array();
$fnames = array();
$lnames = array();
$linha = 0;
foreach($lines as $line) {
if($linha == 0){
}else{
echo $Linha."</br>";
if (strpos($line, ',') !== false) {
$arr = explode(",", $line);
// Email \ FNAME | LAST
$emailx = trim($arr[0]);
$emailx = trim(preg_replace("/[\\n\\r]+/", "", $emailx));
array_push($emails,$emailx);
if(isset($arr[1])){
$fname = trim($arr[1]);
$fname = str_replace('"','',$fname);
array_push($fnames,$fname);
}
if(isset($arr[2])){
$lname = trim($arr[2]);
array_push($lnames,$lname);
}
}else{
array_push($emails,trim($line));
}
}
$linha++;
}
array_map('trim', $emails);
array_map('trim', $fnames);
array_map('trim', $lnames);
$emails = implode(",",$emails);
$fnames = implode(",",$fnames);
$lnames = implode(",",$lnames);
if($insert_list = $this->connect->prepare("INSERT INTO listas(lista_id,email,primeiro_nome,ultimo_nome) VALUES(?,?,?,?)")){
$insert_list->bind_param("isss", $list_id,$emails,$fnames,$lnames);
$insert_list->execute();
$this->mensagem(2,"Lista adicionada com sucesso");
}else{
echo
'
<div class="alert alert-danger">
Erro: '.$this->connect->error.'
</div>
';
}
}else{
echo
'
<div class="alert alert-danger">
Erro: '.$this->connect->error.'
</div>
';
}
}
FIXED this adding this on top of the function :
ini_set('auto_detect_line_endings',true);
I am not sure this is an 'answer' to what is going on, though it is what I had to do to fix an issue with a Mac user sending files.
What I found was that, every time he did an upload, it would send a .zip file, not just the file (like the PCs did). I did not have other Mac users to test against, so, again, I can't say this is exactly the issue you have, but I trust it will at least help in your search.
Note that I had to chop a lot of code out of this (where I was doing various other functions with the database, etc.), so this may not run directly, but I think I closed all the 'ifs' and such - or you can figure it out (if not, let me know and I'll go through it again).
Hope this helps!
$save_file = basename($_FILES["fileToUpload"]["name"]);
$zipfile='maps/'.$save_file; // location of a temp location (stops double uploads)
$alert_upload_file_exists = "Uploaded file exists!";
$alert_upload_successful = "UPLOAD SUCCESSFUL";
$action_failed_text = "Action FAILED";
if(file_exists($zipfile) && (empty($_GET['overwrite']) || $_GET['overwrite'] == 'false'))
die($alert_upload_file_exists);
if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $zipfile))
{
// I found this mac to be sending a .zip file, not a standard one..... :(
$uploadOk = 0;
$mac_file = 0;
if($basename = basename($_FILES["fileToUpload"]["name"],".zip"))
{
$zip = new ZipArchive;
if($zip->open($zipfile) === true){
// echo "basename is $basename<BR>";
for($i = 0; $i < $zip->numFiles; $i++) {
$filename = $zip->getNameIndex($i);
$fileinfo = pathinfo($filename);
// look for the file we really want (in our case, any sort of img file)
if($fileinfo['basename'] == $basename . '.png' || $fileinfo['basename'] == $basename . '.jpg' || $fileinfo['basename'] == $basename . '.gif') {
$imgfile = $_GET['loc_data_id'].".".$fileinfo['extension'];
$files[]=$fileinfo['basename'];
// echo "file added to the list <BR>";
}
// echo "filename is $filename, basename is ->".$fileinfo['basename']."<- fileinfo = ";print_r($fileinfo);
// CHECK TO SEE IF THIS WAS THE 'WEIRD' MAC FILE
if($fileinfo['basename'] == "__MACOSX")
$mac_file = 1;
// echo "mac_file is $mac_file ";
}
if(($imglist = array_keys(array_flip(preg_grep('/^.*\.(jpg|jpeg|png|gif)$/i',$files))))
{
// echo "imglist = ";print_r($imglist);
// echo "files = ";print_r($files);
foreach($files as $key => $value)
{
if ($imglist[0]==$value) {$file = $imgfile;}
$upgrade += file_exists('maps/'.$file);
// echo "imgfile is $imgfile, file is $file upgrade is $upgrade and value is ".$basename."/".$value." ............";
// more 'FUNNY BUSINESS' to work the Mac file....
if($mac_file){
$extracted = $zip->extractTo('maps/',$basename."/".$value);
rename("maps/$basename/$value","maps/$file");
}
else {
$extracted = $zip->extractTo('maps/',$value);
rename("maps/$value","maps/$file");
}
}
// AND A BIT MORE.....
if($mac_file){
rmdir ("maps/$basename");
}
$zip->close();
$imgcount=0;$mapcount=0;$uploadOk=1;
$html = file_get_html('maps/'.$mapfile);
$imgck = strpos($html,'<img ');
if(($imgck===false) || $imgck<>0) {
$uploadOk += 2;
}
// echo "uploadOk is $uploadOk<br>";
if($uploadOk==1)
{
$mapname = pathinfo('maps/'.$mapfile);
// echo "mapfile is $mapfile, mapname = ";print_r($mapname);
}
}
else $uploadOk += 20;
}
}
if($uploadOk==1) echo basename($_FILES["fileToUpload"]["name"])." ".$alert_upload_successful;
else echo $action_failed_text . " ".$uploadOk;
// delete the original .zip file (and any that are in the 'maps/' folder)
array_map('unlink', glob("maps/*.zip"));
}
else
{
echo "Sorry, there was an error uploading your file.";
echo "temp name is " . $_FILES["fileToUpload"]["tmp_name"]. " save file is ". $save_file."<br>";
}

PHP fileupload giving all filenames from array

I've been looking in this for a day or two now.
When I upload multiple files to this script, "$finalfilename" give's me back multiple filenames from the second file.
Here's my code:
include ($_SERVER['DOCUMENT_ROOT'] . "/config/config.php");
$valid_extensions = array(
'jpeg',
'jpg',
'png',
'gif',
'bmp'
); // valid extensions
$path = $_SERVER['DOCUMENT_ROOT'] . '/assets/uploads/'; // upload directory
$uploadOK = 1;
$album = strip_tags($_POST['newPostForm-Album']);
$i = 0;
foreach($_FILES['NEW-POST-FORM_IMAGES']['name'] as $file)
{
$imgname = $_FILES['NEW-POST-FORM_IMAGES']['name'][$i];
$tmpname = $_FILES['NEW-POST-FORM_IMAGES']['tmp_name'][$i];
$timestamp = time();
$extension = strtolower(pathinfo($imgname, PATHINFO_EXTENSION));
$newfilename = sha1(time() . $i);
$finalfilename = $newfilename . "." . $extension;
if ($_FILES['NEW-POST-FORM_IMAGES']["size"][$i] > 500000)
{
echo "Sorry, your file is too large.";
$uploadOk = 0;
}
if ($uploadOK)
{
if (in_array($extension, $valid_extensions))
{
$path = $path . strtolower($finalfilename);
if (move_uploaded_file($tmpname, $path))
{
// mysqli_query($con, "INSERT INTO posts VALUES('', '$album', '$finalfilename', '$timestamp')");
echo $_FILES['NEW-POST-FORM_IMAGES']['name'][$i];
}
else
{
echo "error!";
}
}
}
$imgname = "";
$tmpname = "";
$timestamp = "";
$extension = "";
$newfilename = "";
$finalfilename = "";
$i++;
}
As you can see, I tried resetting all the strings at the end before adding $i.
UPDATE
I tried using $file instead of $_FILES (echo $file['name'][$i];)
This gives me back this warning:
Illegal string offset 'name' in
also the output of the second file ($finalfilename) gives me 'filename'.extention'filename'.extention
ea5816965b01dae0b19072606596c01efc015334.jpeg21aa3008f90c89059d981bdc51b458ca1954ab46.jpg
Wich need to be separated.
I need to only get the filename of each file seperatly.
Thank you!
Problem is in $path variable.
Put $path = $_SERVER['DOCUMENT_ROOT'] . '/assets/uploads/'; into the loop. You can remove variable reseting from the end too.
foreach ($_FILES['NEW-POST-FORM_IMAGES']['name'] as $file) {
$path = $_SERVER['DOCUMENT_ROOT'] . '/assets/uploads/';
$imgname = $_FILES['NEW-POST-FORM_IMAGES']['name'][$i];
$tmpname = $_FILES['NEW-POST-FORM_IMAGES']['tmp_name'][$i];
$timestamp = time();
$extension = strtolower(pathinfo($imgname, PATHINFO_EXTENSION));
$newfilename = sha1(time() . $i);
$finalfilename = $newfilename . "." . $extension;
if ($_FILES['NEW-POST-FORM_IMAGES']["size"][$i] > 500000)
{
echo "Sorry, your file is too large.";
$uploadOk = 0;
}
if ($uploadOK)
{
if (in_array($extension, $valid_extensions))
{
$path = $path . strtolower($finalfilename);
if (move_uploaded_file($tmpname, $path))
{
// mysqli_query($con, "INSERT INTO posts VALUES('', '$album', '$finalfilename', '$timestamp')");
echo $_FILES['NEW-POST-FORM_IMAGES']['name'][$i];
}
else
{
echo "error!";
}
}
}
$i++;
}
There are more thing to update, instead of foreach for/while would be better here, or using foreach in else way (use $file in the loop body), etc. Moving $path into loop is easiest way how to fix your problem.

Multiple input file in one form

I have form :
<form method="post" enctype="multipart/form-data" action="edit_kategori.php">
<input type="file" name="icon-main" id="icon-main">
<input type="file" name="icon-hover" id="icon-hover">
<form>
I want to upload two images from two input files, but only the last one file I have choosen that uploaded. and here is my php:
$dirMain = $_FILES['icon-main']['tmp_name'];
$dirHover = $_FILES['icon-hover']['tmp_name'];
//main icon
$tempMain = explode(".", $_FILES['icon-main']['name']);
$newMain = round(microtime(true)) . '.' . end($tempMain);
$iconMain = $folder . basename($newMain);
//hover icon
$tempHover = explode(".", $_FILES['icon-hover']['name']);
$newHover = round(microtime(true)) . '.' . end($tempHover);
$iconHover = $folder . basename($newHover);
if (!empty($dirMain)&&!empty($dirHover)) {
$dir[] = $dirMain;
$dir[] = $dirHover;
$icon[] = $iconMain;
$icon[] = $iconHover;
for ($i=0; $i <= 1; $i++) {
move_uploaded_file($dir[$i] , $icon[$i]);
}
}
Is that because "tmp_name" can only store one file ? Thanks for helping :)
Just small mistake, loop through <= 1
for ($i=0; $i <= 1; $i++) {
move_uploaded_file($dir[$i] , $icon[$i]);
}
I guess storing $_FILES['yourvar']['tmp_name'] is causing issue. I have tried this both ways and it might useful to you the difference:
Method 1: (working)
move_uploaded_file($_FILES['icon-main']['tmp_name'], $_FILES['icon-main']['name']);
move_uploaded_file($_FILES['icon-hover']['tmp_name'], $_FILES['icon-hover']['name']);
Method 2: (not working)
$d = $_FILES['icon-main']['tmp_name'];
$k = $_FILES['icon-hover']['tmp_name'];
move_uploaded_file($d, $_FILES['icon-main']['name']);
move_uploaded_file($k, $_FILES['icon-hover']['name']);
I just find the way, I move file manualy using if, not looping...
$target = "../category/";
$dir = $target . basename( $_FILES['icon-main']['name']);
if(move_uploaded_file($_FILES['icon-main']['tmp_name'], $dir)) {
echo "<br>";
echo $dir;
} else {
echo "Fail";
};
$dir = $target . basename( $_FILES['icon-hover']['name']);
if(move_uploaded_file($_FILES['icon-hover']['tmp_name'], $dir)) {
echo "<br>";
echo $dir;
} else {
echo "Fail";
};

Multiple image upload, change name if image already exists

I have a code that changes image names like in the windows systems. If there is a image like cup.jpg, the code changes the name into cup0.jpg.
The problem however, is when I'm uploading many images from array and only some of the images already exist and need to get the name changed.
What changes need to be made for this to work with multiple files?
for($i=0; $i<count($_FILES['upload']['name']); $i++) {
$target_file = $target_dir . basename($_FILES["upload"]["name"][$i]);
$images[] = basename($_FILES['upload']['name'][$i]);
}
if (file_exists($target_file)) {
$i = 0;
echo " Image exists, changing name.";
while (file_exists($target_file)) {
$extension = pathinfo($target_file, PATHINFO_EXTENSION);
$filename = pathinfo($target_file, PATHINFO_FILENAME);
$new_filename = $filename . $i . $iterator . '.' . $extension;
$target_file = $target_dir . $new_filename;
$i++;
$images[] = $new_filename;
}
}
I tried adding a loop but the code doesn't work if the array consists of new images and already existing images so only some of the images would need their names changed.
Here are you go:
$images = array();
for($i=0; $i<count($_FILES['upload']['name']); $i++) {
getUniqueName(basename($_FILES["upload"]["name"][$i]),$images);
}
function getUniqueName ($name, &$images) {
$i = 0;
$extension = pathinfo($name, PATHINFO_EXTENSION);
$filename = pathinfo($name, PATHINFO_FILENAME);
while (in_array($name, $images)) {
$name = $filename . $i . '.' . $extension;
$i++;
}
/* Need to define $target_dir here */
$i=0;
while (file_exists($target_dir.$name)) {
$name = $filename . $i . '.' . $extension;
$i++;
}
$images[]= $target_dir.$name;
}

How to explode a file extension from a filename that is in an array?

function addFlyer($db) {
if (isset($_FILES['file_array'])) {
$name_array = $_FILES['file_array']['name'];
$tmp_name_array = $_FILES['file_array']['tmp_name'];
$type_array = $_FILES['file_array']['type'];
$size_array = $_FILES['file_array']['size'];
$error_array = $_FILES['file_array']['error'];
for ($i = 0; $i < count($tmp_name_array); $i++) {
if (file_exists($name_array[$i])) {
echo "Sorry file already exists. ";
$uploadOk = 0;
}
else {
if (move_uploaded_file($tmp_name_array[$i], "images/" . $name_array[$i])) {
echo $name_array[$i] . " upload is complete<br>";
} else {
echo "move_uploaded_file function failed for " . $name_array[$i] . "<br>";
}
}
}
}
At the moment I got this code for upload multiple files to a folder and insert it into the database (I excluded the code for inserting.)
But if I want to use the file_exists function correctly I need to seperate the extension and the name from the file. But I have no idea how I can explode an array.
Is there someone that can help me with this?
You don't need to explode or something else. You could get image extension by path_info() PHP Function. PLease have a look on below.
$path = $_FILES['file_array']['name'];
$ext = pathinfo($path, PATHINFO_EXTENSION);
If you want to explode a file name. You can use below trick
$file = $_FILES['file_array']['name'];
$image_info = explode(".", $file);
$image_type = end($image_info)
foreach ($name_array as $value) {
if (file_exists($value)) {
echo "Sorry file already exists. ";
$uploadOk = 0;
} else {
if (move_uploaded_file($value, "images/" . $value)) {
echo $value . " upload is complete<br>";
} else {
echo "move_uploaded_file function failed for " . $value . "<br>";
}
}
}
This may work. Use foreach() loop instead of for() loop.

Categories