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

How to prevent duplicate filenames in 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 中最好的解决方法是什么?

非常感谢您的帮助。

您可以做一些事情。

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

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

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

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