Check if a file exists and rename another file if the file exists


<?
	
	if (file_exists($path))
	{
		$i= 1;
		
		while (file_exists($path))
		{
			// get file extension
			$extension = pathinfo($path, PATHINFO_EXTENSION);
			
			// get file's name
			$filename = pathinfo($path, PATHINFO_FILENAME);
			
			// add and combine the filename, iterator, extension
			$new_filename = $filename . '-' . $iterator . '.' . $extension;
			
			// add file name to the end of the path to place it in the new directory; the while loop will check it again
			$path = $directory . $new_filename;
			$i++;
			
		}
	}
?>




This code is supposed to rename a file, if it exists, to the name of that file with a hypen and a number. Example: “word_document.doc” to “word_document-1.doc”. And if word_document-1.doc exists, rename it to word_document-2.doc, and so on. Instead, if a file exists, I get word-document-1.doc (works the first time) but then it just adds the iterator instead of substituting it for files that follow with the same name. So I get word_document-1-2.doc, and word_document-1-2-3.doc. I think I can see why this is happening, the new file variable contains the previous while loop’s iterator, but I don’t know how to fix it without using some regex to detect the previous iterator, and I think that is probably not needed here. Please help.

You’ll need to save the new path outside of the loop so it can be referenced and checked.

Something like this:

if (file_exists($path))     { 
        $i=1; 
		$new_path=$path;
         
        while (file_exists($new_path)) 
        { 
            // get file extension 
            $extension = pathinfo($path, PATHINFO_EXTENSION); 
             
            // get file's name 
            $filename = pathinfo($path, PATHINFO_FILENAME); 
			
			// get file's directory
			$directory=dirname($path);
             
            // add and combine the filename, iterator, extension 
            $new_filename = $filename . '-' . $i . '.' . $extension; 
             
            // add file name to the end of the path to place it in the new directory; the while loop will check it again 
            $new_path = $directory . $new_filename; 
			
            $i++;  
        } 
		
		if(!rename($path, $new_path)){
			echo 'error renaming file';
		}
    } 

Just wanted to say thank you for this. It really helped.

No need to define $directory, $filename and $extension in the while loop, as they will never change for different iterations.
Also, you only need to rename the file if it actually needs to be renamed, otherwise there is no need to bother.


list($directory, , $extension, $filename) = array_values(pathinfo($path));

$i = 0;
while (file_exists($path))
{ 
    $new_path = $directory . '/' . $filename . '-' . $i . '.' . $extension;
    $i++;
} 

if ($path !== $new_path && !rename($path, $new_path))
{
    throw new Exception('Error renaming `'.$path.'` to `'.$new_path.'`');
}

:slight_smile:

That’s a good catch. I am always looking to improve my loop performance, so thanks for the update.