laravel使用Storage门面的putFile方法保存文件

2019-03-13  本文已影响0人  BigFish__

通过接口上传的文件是一个.glb后缀结尾的3d模型文件,保存文件的代码如下:

$dataPath = Storage::disk('public')->putFile('models', $request->file('model'));

使用的是Storage门面的putFile方法,但是保存之后的文件名后缀是以.bin结尾的,而不是原文件的.glb,这样子当我把$dataPath变量入库,后面前端需要数据的时候拿到的就是.bin后缀的路径,造成了模型在前端无法正常展示的问题。

问题的原因在于putFile方法默认会去猜文件的类型,然后使用相应的后缀名,而不是保留原来的用户名。这一点在laravel的官网文档里面有指出:

By default, the putFile method will generate a unique ID to serve as the file name. The file's extension will be determined by examining the file's MIME type. The path to the file will be returned by the putFile method so you can store the path, including the generated file name, in your database.

通过查看这个方法的源码也可以找到原因:

    /**
     * Store the uploaded file on the disk.
     *
     * @param  string  $path
     * @param  \Illuminate\Http\File|\Illuminate\Http\UploadedFile  $file
     * @param  array  $options
     * @return string|false
     */
    public function putFile($path, $file, $options = [])
    {
        return $this->putFileAs($path, $file, $file->hashName(), $options);
    }

hashName方法的代码:

    /**
     * Get a filename for the file.
     *
     * @param  string  $path
     * @return string
     */
    public function hashName($path = null)
    {
        if ($path) {
            $path = rtrim($path, '/').'/';
        }

        $hash = $this->hashName ?: $this->hashName = Str::random(40);

        if ($extension = $this->guessExtension()) {
            $extension = '.'.$extension;
        }

        return $path.$hash.$extension;
    }

putFile方法是没有传入文件名的,所以hasName会使用Strhelper创建一个40位的随机字符串作为文件名,然后使用gesssExtension方法去“猜”此文件的后缀。

找到原因之后将原来的代码改造一下就可以解决问题:

$dataNewName = Str::random(40) . '.' .$request->file('model')->getClientOriginalExtension();
$dataPath = Storage::disk('public')->putFileAs('models', $request->file('model'), $dataNewName);

这里使用了getClientOriginalExtension方法来获取原始文件的后缀,然后使用putFileAs方法来保存文件,同时指定文件名。

参考资料:
Laravel - File Storage

上一篇下一篇

猜你喜欢

热点阅读