views:

73

answers:

3

Hi.
I use the following function to rename thumbnails.
For example, if I upload a file called "image.png" to an upload folder, and this folder already has a file named "image.png" in it, the new file automatically gets renamed to "image-copy-1.png". If there also is a file called "image-copy-1.png" it gets renamed to "image-copy-2.png" and so on.
The following function returns the new filename. At least that's what it is supposed to do...
The renaming doesn't seeem to work correctly, though. Sometimes it produces strange results, like: (I always uploaded a file named "1.png")
1-copy-1.png
1-copy-2.png
1-copy-2-copy-1.png
1-copy-2-copy-3.png

I hope you understand my problem, despite my description being somewhat complex... Can you tell me what went wrong here? (bonus question: Is regular expressions the right tool for doing this kind of stuff?)

<?php
function renameDuplicates($path, $file)
{   
    $fileName = pathinfo($path . $file, PATHINFO_FILENAME);
    $fileExtension = "." . pathinfo($path . $file, PATHINFO_EXTENSION);

    if(file_exists($path . $file))
    {
        $fileCopy = $fileName . "-copy-1";

        if(file_exists($path . $fileCopy . $fileExtension))
        {           
            if ($contains = preg_match_all ("/.*?(copy)(-)(\\d+)/is", $fileCopy, $matches))
            {
                $copyIndex = $matches[3][0];            
                $fileName = substr($fileCopy, 0, -(strlen("-copy-" . $copyIndex))) . "-copy-" . ($copyIndex + 1);
            }                       
        }

        else
        {
            $fileName .= "-copy-1";
        }
    }

    $returnValue = $fileName . $fileExtension;  
    return $returnValue;
}?>
A: 

when it rename the file like 1-copy-2-copy-1.png what is the name of the file you are uploading?

Because:
if the file has this name 1-copy-2.png it's normal to have 1-copy-2-copy-1.png as a renamed file...

otherwise there is a problem :)

Marcx
I always uploaded a file named "1.png".
snorpey
+2  A: 

Simpler, without regex;

function renameDuplicates($path, $file)
{   
    $fileName = pathinfo($path . $file, PATHINFO_FILENAME);
    $fileExtension = "." . pathinfo($path . $file, PATHINFO_EXTENSION);

    $returnValue = $fileName . $fileExtension;

    $copy = 1;
    while(file_exists($path . $returnValue))
    {
        $returnValue = $fileName . '-copy-'. $copy . $fileExtension;
        $copy++;
    }
    return $returnValue;
}

Quick benchmark for performance issues (32000 is max files in folder):

$start = microtime(1);
$c=0;
while($c<32000)
    if(file_exists(__FILE__))
        $c++;
echo microtime(1) - $start; /* 0.44202709197998 */

So less than half second for worst-case scenario. And for 100 copies - 0.0013940334320068 s. And as for regex:

$start = microtime(1);
$contains = preg_match_all ("/.*?(copy)(-)(\\d+)/is", __FILE__, $matches);
echo microtime(1) - $start; /* 0.010906934738159 */ 

so if you plan to have more than ~800 copies of one file regex will be faster (by some microseconds, but faster) :)

dev-null-dweller
Thanks a lot for your answer (and for answering the bonus question as well)!
snorpey
A: 

It looks like your code only checks if a file copy named 1-copy-1.png exists? And when it finds it it renames it to 1-copy-2.png

However it doesnt check if a file 1-copy-2.png exists and doesnt increment that.

But in your solution the script need to check every file in the folder. So if there are many files. It will be slow.

Sinan