Laravel S3图像上传会自动创建一个包含文件名的文件夹

时间:2018-02-14 08:51:13

标签: php laravel laravel-5 amazon-s3 file-upload

我使用的是Laravel 5.4。*。我在帮助文件中使用这个简单的代码在S3桶中上传图像/ gif,名为say" instant_gifs /"。代码如下:

if ( !function_exists('uploadFile') ) {

function uploadFile($fileContent, $fileName, $size='full', $disk='s3')
{
    $rv = '';
    if( empty($fileContent) ) {
        return $rv;
    }

    if($size == 'full') {
        dump($fileName);

        $path = Storage::disk($disk)->put(
                    $fileName,
                    $fileContent,
                    'public'
                );
    }

    if ( $path ) {
        $rv = $fileName;
    }

    return $rv;
}

}

在控制器中,我调用了如下的辅助方法:

$file = $request->gif;
$file_name = 'instant_gifs/' . $user_id . '_' . time() . '_' . $file->getClientOriginalName();
$result = uploadFile($file, $file_name);

在帮助方法的$ fileName参数中,我提供了fileName,例如以这种格式:

  

" instant_gifs / 83_1518596022_giphy.gif"

但上传后,我发现该文件存储在此文件夹

  

" vvstorage / instant_gifs / 83_1518596022_giphy.gif / CRm1o1YEcvX3fAulDeDfwT7DIMCxOKG8WFGcA3lB.gif"

随机文件名

  

CRm1o1YEcvX3fAulDeDfwT7DIMCxOKG8WFGcA3lB.gif

然而,根据代码,它应该存储在这条路径中:

  

" vvstorage / instant_gifs / 83_1518596022_giphy.gif"

没有得到任何解释为什么会发生这种情况。任何线索将不胜感激。

BucketName = vvstorage
文件夹我模仿= instant_gifs

2 个答案:

答案 0 :(得分:6)

经过一番研究和研究测试,发现问题。 put()方法期望第二个参数作为文件内容或流而不是文件对象。在我的代码中,我发送文件为$file = $request->gif;$file = $request->file('gif');,希望Storage类隐式获取文件内容。但是为了获得预期的结果,我需要从控制器调用helper方法,如下所示。请注意 file_get_contents()部分。

$file = $request->gif;
$file_name = 'instant_gifs/' . $user_id . '_' . time() . '_' . $file>getClientOriginalName();
$result = uploadFile( file_get_contents($file), $file_name );

现在,我将图像正确存储在正确的路径下,例如/instant_gifs/9_1518633281_IMG_7491.jpg

现在,让我比较/总结实现相同结果的可用方法:

1)put()

 $path = Storage::disk('s3')->put(
                    '/instant_gifs/9_1518633281_IMG_7491.jpg', #$path
                    file_get_contents($request->file('gif')), #$fileContent
                   'public' #$visibility

将其存储在/vvstorage/instant_gifs/9_1518633281_IMG_7491.jpg

2)putFileAs():要与putFileAs()实现相同的目标,我需要按如下方式编写。第一个参数需要目录名,我把它留空了,因为我正在通过文件名模仿s3中的目录名。

$path = Storage::disk('s3')->putFileAs(
                '', ## 1st parameter expects directory name, I left it blank as I'm mimicking the directory name through the filename
                '/instant_gifs/9_1518633281_IMG_7491.jpg',
                $request->file('gif'), ## 3rd parameter file resource
                ['visibility' => 'public'] #$options
            );

将其存储在/vvstorage/instant_gifs/9_1518633281_IMG_7491.jpg

3)storeAs()

$path = $request->file('gif')->storeAs(
             '', #$path
             '/instant_gifs/9_1518633281_IMG_7491.jpg', #$fileName
             ['disk'=>'s3', 'visibility'=>'public'] #$options
             );    

将其存储在/vvstorage/instant_gifs/9_1518633281_IMG_7491.jpg

<强>附加功能:: 4)用于通过put()存储缩略图。 stream()...

的示例
$imgThumb = Image::make($request->file('image'))->resize(300, 300)->stream(); ##create thumbnail
        $path = Storage::disk('s3')->put(
                    'profilethumbs/' . $imgName,
                    $imgThumb->__toString(),
                    'public'
                );

希望它可以帮助某人。

答案 1 :(得分:1)

1。)为什么网址中有const $lastCells = $('tr').map((i, element) => $(element).children().last()[0] ); console.log($lastCells);

它附加了该路线,因为vvstorage root内的configuration文件夹设为S3,因此每当您上传到vvstorage时文件将以S3为前缀。

2。)为什么即使你传递了文件的名称,随机名称?

因为当使用vvstorage时,文件将生成put生成并设置为文件名,因此无论您传递什么,它都不会以您想要的名称保存文件。但是如果你使用unique ID,那么你可以覆盖putFileAs的默认行为并传递文件的名称。

希望这能澄清它