2010-03-14 4 views
1

Я использую следующую функцию для переименования миниатюр.
Например, если я загружаю файл с именем «image.png» в папку для загрузки, и в этой папке уже есть файл с именем «image.png», новый файл автоматически переименовывается в «image-copy-1» .png». Если также есть файл с именем «image-copy-1.png», он переименовывается в «image-copy-2.png» и так далее.
Следующая функция возвращает новое имя файла. По крайней мере, это то, что он должен делать ...
Переименование не работает правильно. Иногда это приводит к странным результатам, как: (Я всегда загрузил файл с именем "1.png")
1-копия-1.png
1-копия-2.png
1-копия-2-копия-1 .png
1-copy-2-copy-3.pngпереименовывать файлы с таким же именем.

Надеюсь, вы понимаете мою проблему, несмотря на то, что мое описание несколько сложное ... Можете ли вы сказать мне, что здесь не так? (Бонус вопрос: регулярные выражения правильный инструмент для ведения такого рода вещи?)

<?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; 
}?> 

ответ

2

Simpler, без регулярных выражений;

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; 
} 

Быстрый тест для проблем с производительностью (32000 является не более файлов в папке):

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

Так меньше, чем полсекунды для наихудшего сценария. И за 100 экземпляров - 0,0013940334320068 с. И как для регулярных выражений:

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

так что если вы планируете иметь более чем 800 ~ копий одного файла регулярное выражение будет быстрее (в течение нескольких микросекунд, но быстрее) :)

+0

Большое спасибо за ваш ответ (а также за ответ на вопрос о бонусе)! – snorpey

0

когда это переименовать файл как 1-copy-2-copy-1.png, что это имя файла, который вы загружаете?

Потому что:
, если файл с таким именем 1-copy-2.png это нормально, чтобы иметь 1-copy-2-copy-1.png как переименованный файл ...

иначе есть проблема :)

+0

Я всегда загружал файл с именем «1.png». – snorpey

0

Похоже, ваш код только проверяет, существует ли копия файла с именем 1-copy-1.png? И когда он находит это, он переименовывает его в 1-copy-2.png

Однако он не проверяет, существует ли файл 1-copy-2.png и не увеличивает его.

Но в вашем решении скрипту необходимо проверить каждый файл в папке. Поэтому, если файлов много. Это будет медленно.

Смежные вопросы