2015-02-24 2 views
2

Это код, который у меня есть в магазине, с одного из моих контроллеров.Как предотвратить дублирование имен файлов в laravel?

// Get the file object from the user input. 
    $file = Request::file('filefield'); 

    // Get the filename by referring to the input object 
    $fileName = $file->getClientOriginalName(); 

    if (!Storage::exists($fileName)) 
    { 
     Storage::disk('local')->put($fileName, File::get($file)); 
    } else { 
     return 'Hey this file exist already'; 
    } 

Он отлично работает, но проблема, что у меня было, что это позволило дублированных имен файлов и файл, очевидно, не будет загружать. Я попытался исправить это, и это хорошо.

Теперь я предполагаю, что если я хочу, чтобы пользователь загружал имя файла с таким же именем, которое у меня уже есть, мне нужно добавить что-то вроде номера в имя файла.

Мой вопрос - это лучший способ сделать это в laravel?

Помощь очень ценится.

ответ

7

Есть несколько вещей, которые вы могли бы сделать.

Если исходное имя файла уже существует, следующий код будет искать в нем целое число перед расширением. Если его нет, он добавляет его. Затем он увеличивает это число и проверяет, пока такое имя файла не существует.

if (Storage::exists($fileName)) { 
    // Split filename into parts 
    $pathInfo = pathinfo($fileName); 
    $extension = isset($pathInfo['extension']) ? ('.' . $pathInfo['extension']) : ''; 

    // Look for a number before the extension; add one if there isn't already 
    if (preg_match('/(.*?)(\d+)$/', $pathInfo['filename'], $match)) { 
     // Have a number; increment it 
     $base = $match[1]; 
     $number = intVal($match[2]); 
    } else { 
     // No number; add one 
     $base = $pathInfo['filename']; 
     $number = 0; 
    } 

    // Choose a name with an incremented number until a file with that name 
    // doesn't exist 
    do { 
     $fileName = $pathInfo['dirname'] . DIRECTORY_SEPARATOR . $base . ++$number . $extension; 
    } while (Storage::exists($fileName)); 
} 

// Store the file 
Storage::disk('local')->put($fileName, File::get($file)); 

В качестве альтернативы, вы можете создать уникальную строку, например, с помощью uniqid и добавьте это в исходное имя файла (или использовать его в покое). Если вы это сделаете, у вас будет вероятность столкновения, которая приблизится к нулю, и многие скажут, что даже не стоит проверять, существует ли файл с таким именем или нет.

В любом случае (более того, с первым примером) существует вероятность того, что другой процесс сделает файл между этим, который проверяет, что он не существует, а затем записывает файл. Если это произойдет, вы можете потерять данные. Есть несколько способов смягчить эту возможность, например, используя tempnam.

+0

Спасибо, что добавление uniqid кажется хорошим вариантом и самым простым в реализации. Я попробую. Ваш ответ очень ценится! –

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