while loop in php not working - php

i am new to php, i am trying to upload a file to a url, where php script should have the logic to check if file already exisits, it should append a value to the file name and then check again if it exisits, if not then proceed further to save it.
Here is the while loop:
$target_path = $target_path . basename( $_FILES['userfile']['name']);
$i = 1;
while (true) {
if (file_exists($target_path)) {
$target_path = $i . "_" . $target_path;
$i++;
} else {
break;
}
}
Now, im not sure if break; works the same as in other languages. What i am trying to do is the target path if already exists, will be updated and checked at each iteration of while loop, if it does not exists, the else should break the while loop, and later i will save the file with that name.
It works only if the file does not exisits, after that it just fail to rename the file path.
What is wrong here?

Edited, this should work.
$i = 1;
$base = basename( $_FILES['userfile']['name']);
while (file_exists($target_path.$i.'_'.$base)) {
$i++;
}
$target_path = $target_path.$i.'_'.$base;

Perhaps this little piece of code will help you:
function safeFilename($image_path,$filename_original)
{ $extension = strrchr($filename_original, ".");
$filename_base = substr($filename_original,0,-1*strlen($extension));
$filename = $filename_base;
$counter = 1;
while(file_exists($image_path.$filename.$extension))
{ $filename = $filename_base . $counter;
$counter++;
}
return $filename.$extension;
}
Update: my bad, fixed, thanks for your feedback.

Related

Integer in while loop wont increase value

I'm having a problem in my code, I am trying to append a number to a filename if filename already exists. It goes something like this
$explode = explode(".", $fileName);
$extension = end($explode);
$fileactualname = reset($explode);
$i = 0;
while (file_exists($location.$fileName)) {
$i++;
}
$fileName= $i.$fileName;
$name = $fileName;
$moveResult = move_uploaded_file($fileTmpLoc, $location . "/". $name);
if ($moveResult != true) {
#unlink($fileTmpLoc);
header('location: ' . URL . '?page=0&sort=name&type=desc&folder=uploads/&message=uploaderror');
}
Unfortunately for some reason $i wont increase its value by 1 every time it loops, instead it adds to the filename this way 1234filename.jpg my file name variable is after the loop and i cant understand why this is accruing. I am expecting to get ($i)filename.jpg a single number
AFTER RESTARTING MY LOCALSERVER IT STARTED WORKING WITH THE CODE PROVIDED BELOW DUUUH
You need to use the actual filename when you concat the number to it and not the one you already added a number to.
// not sure why you are splitting the filname up here
$explode = explode(".", $fileName);
$extension = end($explode);
$fileactualname = reset($explode);
$i = 0;
$fn = $fileName;
while (file_exists($location.$fn)) {
$i++;
// add number to actual filename
$fn = $i.$fileName;
}
$name = $fn;
$moveResult = move_uploaded_file($fileTmpLoc, $location . "/". $name);

How to increment a value without any for loop but based on number of times the file is run in PHP

I have a script which, when it runs, creates a new file in some directory. While creating a new file it checks if the file exists:
If it exists it should append 1 to the file name
If another file has same name it should increment and append 2.
$filecount = 0;
if (! file_exists ( SOME_DIR . $fileName )) {
echo "not there";
//so save normally
} else {
echo "there";
$fileName = $fileName."_" .$file_count++.".txt";
// save with number at the end
}
Currently, when the file is run multiple times it is only saving with number for the first time, as the variable $filecount is again set to 0.
Is there any work around to increment filename when its name is repeated?
You can do like this
<?php
define('SOME_DIR', '');
$fileName = 'file';
if (! file_exists ( SOME_DIR . $fileName.'.txt' )) {
echo "not there";
//so save normally
}
else{
$files = glob(SOME_DIR.$fileName.'_*.txt');
$counter = count($files)+1;
echo "there";
$fileName = $fileName."_" .$counter.".txt";
echo $fileName;
// save with number at the end
}
Tested, working well for me
You need to store somewhere the number of runs of your script. If you are already writing files I would use an plain text file to store the number of runs.
Other options is to use a timestamp as file name deduplicator.
define('SOME_DIR', __DIR__ . '/');
$basename = 'test.txt';
$path = SOME_DIR . $basename;
// Consider clearing stat cache before using `file_exists` and similar
// functions that run `stat`, or `lstat` system calls under the hood.
clearstatcache(true, $path);
if (file_exists($path)) {
$filename = pathinfo($basename, PATHINFO_FILENAME);
$ext = pathinfo($basename, PATHINFO_EXTENSION);
$files = glob(SOME_DIR . "${filename}_[0-9]*.${ext}", GLOB_BRACE);
$basename = sprintf(
'%s_%d.%s',
$filename,
(count($files) + 1),
$ext
);
$path = SOME_DIR . $basename;
}
// Replace with your logic
touch($path);

How to increment unique filename based on directory array

I'm creating an upload form that when uploading files will check to see if a file with the same name already exists in the directory. If a file with the same name is found, the script should increment the file by appending the file name with a number such as test1.txt test2.txt and so on until a match is not found. This is what I have come up with so far but wanted to see if there is a different approach I should take.
Also note, my filenames are already cleaned before they enter this part of the script so my filename and extension functions are simplified.
function filename($file){
return substr($file,0,strrpos($file,'.'));
}
function extension($file){
return strtolower(substr(strrchr($file,'.'),1));
}
$new_file = 'test.txt';
$dir = 'files';
$files = scandir($dir);
$exclude = array('.','..');
foreach($files as $file){
if(!in_array($file,$exclude)){
$file_array[] = $file;
}
}
$i = 1;
while(in_array($new_file,$file_array)){
$filename = filename($new_file);
$extension = extension($new_file);
if($i>1){
$num = strlen($filename);
$filename = substr($filename,0,-1);
$new_file = $filename.$i.'.'.$extension;
} else {
$new_file = $filename.$i.'.'.$extension;
}
echo $new_file.'<br>';
echo $i.'<br>';
$i++;
}
echo $new_file;

How to rename each file before uploading to server to a time-stamp

I'm using the following code to upload some files, but well, some get replaced since the names get to be alike. I just wanna know how do i change the name, i tried but i kinda find myself messing the entire code.
PHP
if (!empty($_FILES["ambum_art"])) {
$myFile = $_FILES["ambum_art"];
if ($myFile["error"] !== UPLOAD_ERR_OK) {
echo "<p>An error occurred.</p>";
exit;
}
$name = preg_replace("/[^A-Z0-9._-]/i", "_", $myFile["name"]);
$i = 0;
$parts = pathinfo($name);
while (file_exists(UPLOAD_DIR . $name)) {
$i++;
$name = $parts["filename"] . "-" . $i . "." . $parts["extension"];
}
$success = move_uploaded_file($myFile["tmp_name"],UPLOAD_DIR . '/'.$name);
if (!$success) {
echo "<p>Unable to save file.</p>";
exit;
} else {
$Dir = UPLOAD_DIR .'/'. $_FILES["ambum_art"]["name"];
}
chmod(UPLOAD_DIR .'/'. $name, 0644);
unset($_SESSION['video']);
$_SESSION['album_art'] = $Dir;
$ambum_art_result = array();
$ambum_art_result['content'] = $Dir;
echo json_encode($ambum_art_result);
}
I would like each file to have something from this variable generated from time.
$rand_name = microtime().microtime().time().microtime();
Thanks.
I don't want to first check if file exists as that adds to the processes, i just want to use time() and some random string. to just get a unique name.
Please see this website for a decent example of file uploading and an explanation. Also this site appears to be where you found this particular script from or if not offers a good explanation.
I have modified your code to include some comments so you and others can understand what is going on better. In theory, the code shouldn't be overwriting existing files like you say it does but I have added what you would need to change to set the name of the file to a random string.
In addition you are storing the original filename into the session and not the modified filename.
define("UPLOAD_DIR", "/path/to/uploads/");
if (!empty($_FILES["ambum_art"]))
{
// The file uploaded
$myFile = $_FILES["ambum_art"];
// Check there was no errors
if ($myFile["error"] !== UPLOAD_ERR_OK) {
echo "<p>An error occurred.</p>";
exit;
}
// Rename the file so it only contains A-Z, 0-9 . _ -
$name = preg_replace("/[^A-Z0-9._-]/i", "_", $myFile["name"]);
// Split the name into useful parts
$parts = pathinfo($name);
// This part of the code should continue to loop until a filename has been found that does not already exist.
$i = 0;
while (file_exists(UPLOAD_DIR . $name)) {
$i++;
$name = $parts["filename"] . "-" . $i . "." . $parts["extension"];
}
// If you want to set a random unique name for the file then uncomment the following line and remove the above
// $name = uniqid() . $parts["extension"];
// Now its time to save the uploaded file in your upload directory with the new name
$success = move_uploaded_file($myFile["tmp_name"], UPLOAD_DIR . '/'.$name);
// If saving failed then quit execution
if (!$success) {
echo "<p>Unable to save file.</p>";
exit;
}
// Set file path to the $Dir variable
$Dir = UPLOAD_DIR .'/'. $name;
// Set the permissions on the newly uploaded file
chmod($Dir, 0644);
// Your application specific session stuff
unset($_SESSION['video']);
$_SESSION['album_art'] = $Dir; // Save the file path to the session
$ambum_art_result = array();
$ambum_art_result['content'] = $Dir;
echo json_encode($ambum_art_result);
}
Read more about PHPs uniqid.
I would also strongly advise doing some filetype checking as currently it appears as though any file can be uploaded. The second link above has a section titled 'Security Considerations' that I would recommend reading through vary carefully.
This code is filtering the name, then checks if file with exactly same name is already sent. If it is - name is changed with with number.
If you want to change the file name as in many sites - you may modify this line $name = preg_replace("/[^A-Z0-9._-]/i", "_", $myFile["name"]);
For example into: $name = time().'_'.preg_replace("/[^A-Z0-9._-]/i", "_", $myFile["name"]);
If user sends file calle 'hello.jpg' this code will change it to _hello.jpg if file with the same name exists already the name _hello-.jpg will be used instead.
First you need to copy that file which you want to upload and after that you have to rename that. Ex.
//copy
if (!copy($file, $newfile)) {
echo "failed to copy $file...\n";
}
?>
//rename
rename('picture', 'img506.jpg');
Reference Link for copy
Rename file
Edited:
Replace your code with this and then try
<?php
if (!empty($_FILES["ambum_art"])) {
$myFile = $_FILES["ambum_art"];
if ($myFile["error"] !== UPLOAD_ERR_OK) {
echo "<p>An error occurred.</p>";
exit;
}
$name = preg_replace("/[^A-Z0-9._-]/i", "_", $myFile["name"]);
$i = 0;
$parts = pathinfo($name);
while (file_exists(UPLOAD_DIR . $name)) {
$i++;
$name = $parts["filename"] . "-" . $i . "." . $parts["extension"];
}
if (file_exists($myFile["name"])) {
rename($myFile["name"], $myFile["name"].time()); //added content
}
$success = move_uploaded_file($myFile["tmp_name"],UPLOAD_DIR . '/'.$name);
if (!$success) {
echo "<p>Unable to save file.</p>";
exit;
} else {
$Dir = UPLOAD_DIR .'/'. $_FILES["ambum_art"]["name"];
}
chmod(UPLOAD_DIR .'/'. $name, 0644);
unset($_SESSION['video']);
$_SESSION['album_art'] = $Dir;
$ambum_art_result = array();
$ambum_art_result['content'] = $Dir;
echo json_encode($ambum_art_result);
}
?>
This will rename your existing file and then copy your file

PHP fileupload: keep both files if same name

is there any pretty solution in PHP which allows me to expand filename with an auto-increment number if the filename already exists? I dont want to rename the uploaded files in some unreadable stuff. So i thought it would be nice like this: (all image files are allowed.)
Cover.png
Cover (1).png
Cover (2).png
…
First, let's separate extension and filename:
$file=pathinfo(<your file>);
For easier file check and appending, save filename into new variable:
$filename=$file['filename'];
Then, let's check if file already exists and save new filename until it doesn't:
$i=1;
while(file_exists($filename.".".$file['extension'])){
$filename=$file['filename']." ($i)";
$i++;
}
Here you go, you have a original file with your <append something> that doesn't exist yet.
EDIT:
Added auto increment number.
Got it:
if (preg_match('/(^.*?)+(?:\((\d+)\))?(\.(?:\w){0,3}$)/si', $FILE_NAME, $regs)) {
$filename = $regs[1];
$copies = (int)$regs[2];
$fileext = $regs[3];
$fullfile = $FILE_DIRECTORY.$FILE_NAME;
while(file_exists($fullfile) && !is_dir($fullfile))
{
$copies = $copies+1;
$FILE_NAME = $filename."(".$copies.")".$fileext;
$fullfile = $FILE_DIRECTORY.$FILE_NAME;
}
}
return $FILE_NAME;
You can use this function below to get unique name for uploading
function get_unique_file_name($path, $filename) {
$file_parts = explode(".", $filename);
$ext = array_pop($file_parts);
$name = implode(".", $file_parts);
$i = 1;
while (file_exists($path . $filename)) {
$filename = $name . '-' . ($i++) . '.' . $ext;
}
return $filename;
}
Use that function as
$path = __DIR__ . '/tmp/';
$fileInput = 'userfile';
$filename = $path .
get_unique_file_name($path, basename($_FILES[$fileInput]['name']));
if (move_uploaded_file($_FILES[$fileInput]['tmp_name'], $filename)) {
return $filename;
}
You can get working script here at github page
Use file_exists() function and rename() function to achieve what you're trying to do!

Categories