如何防止laravel中的重复文件名?

Ste*_*n-v 2 php upload file laravel eloquent

这是我在我的一个控制器的store方法中的代码.

    // 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';
    }
Run Code Online (Sandbox Code Playgroud)

它工作正常,但我遇到的问题是,它允许重复的文件名,文件显然不会上传.我尝试用这个来修复它,到目前为止这很好.

现在我猜我是否希望用户上传一个名称与我已经拥有的文件名相同的文件名,我需要在文件名中附加一些数字.

我的问题是在laravel中解决这个问题的最佳方法是什么?

非常感谢帮助.

tre*_*mby 8

你可以做一些事情.

如果原始文件名已存在,则以下代码将在扩展名之前查找其中的整数.如果没有,则添加一个.然后它递增此数字并检查,直到这样的文件名不存在.

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; get it
        $base = $match[1];
        $number = intVal($match[2]);
    } else {
        // No number; pretend we found a zero
        $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));
Run Code Online (Sandbox Code Playgroud)

或者,您可以生成一个唯一的字符串,例如with uniqid,并将其附加到原始文件名(或单独使用它).如果你这样做,你就有可能发生碰撞,所以接近于零,许多人会说它甚至不值得检查是否已存在具有该名称的文件.

无论哪种方式(对于第一个示例更是如此),有可能另一个进程使该文件之间的文件验证它不存在然后写入文件.如果发生这种情况,您可能会丢失数据.有一些方法可以减轻这种可能性,例如通过使用tempnam.