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

时间:2015-02-24 23:44:48

标签: php file laravel upload 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';
    }

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

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

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

非常感谢帮助。

1 个答案:

答案 0 :(得分: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