Laravel S3 图像上传自动创建一个带有文件名的文件夹

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/48783020/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 17:23:21  来源:igfitidea点击:

Laravel S3 image upload creates a folder with the filename automatically

phplaravellaravel-5amazon-s3file-upload

提问by usamurai

I'm using Laravel 5.4.*. I've this simple code in a helper file to upload images/gif in S3 bucket under a folder named say "instant_gifs/". The code is below:

我正在使用 Laravel 5.4.*。我在帮助文件中有这个简单的代码,用于在名为“instant_gifs/”的文件夹下上传 S3 存储桶中的图像/gif。代码如下:

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

}

From the controller, I'm calling the helper method as below:

从控制器中,我正在调用 helper 方法,如下所示:

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

In the the $fileName parameter of the helper method, I'm providing the fileName as for example in this format:

在 helper 方法的 $fileName 参数中,我提供文件名,例如以下格式:

"instant_gifs/83_1518596022_giphy.gif"

“instant_gifs/83_1518596022_giphy.gif”

but after the upload, I see that the file gets stored under this folder

但上传后,我看到文件被存储在这个文件夹下

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

“vvstorage/instant_gifs/83_1518596022_giphy.gif/CRm1o1YEcvX3fAulDeDfwT7DIMCxOKG8WFGcA3lB.gif”

with a random file name

带有随机文件名

CRm1o1YEcvX3fAulDeDfwT7DIMCxOKG8WFGcA3lB.gif

CRm1o1YEcvX3fAulDeDfwT7DIMCxOKG8WFGcA3lB.gif

Whereas, according to the code, it should get stored in this path:

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

"vvstorage/instant_gifs/83_1518596022_giphy.gif"

“vvstorage/instant_gifs/83_1518596022_giphy.gif”

Doesn't get any explanation why this is happening. Any clue will be appreciated.

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

BucketName = vvstorage
Folder I'm mimicking = instant_gifs

BucketName =
我正在模仿的vvstorage 文件夹 = instant_gifs

回答by usamurai

After some research & testing, found the issue. put()method expects the 2nd parameter as the file contents or stream not the file object. In my code, I was sending the file as $file = $request->gif;or $file = $request->file('gif');hoping that Storage class will implicitly get the file contents. But to get the expected result, I needed to call the helper method from the controller as below. Notice the file_get_contents()part.

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

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

Now, I got the image correctly stored under the correct path for example in /instant_gifs/9_1518633281_IMG_7491.jpg.

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

Now, let me compare/summarize the available methods for achieving the same result:

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

1) put():

1)放置()

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

Got it stored in /vvstorage/instant_gifs/9_1518633281_IMG_7491.jpg

得到它存储在 /vvstorage/instant_gifs/9_1518633281_IMG_7491.jpg

2) putFileAs(): To achieve the same thing withputFileAs(), I needed to write it as below. 1st parameter expects the directory name, I left it blank as I'm mimicking the directory name in s3 through the filename.

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

Got it stored in /vvstorage/instant_gifs/9_1518633281_IMG_7491.jpg

得到它存储在 /vvstorage/instant_gifs/9_1518633281_IMG_7491.jpg

3) storeAs():

3) storeAs()

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

Got it stored in /vvstorage/instant_gifs/9_1518633281_IMG_7491.jpg

得到它存储在 /vvstorage/instant_gifs/9_1518633281_IMG_7491.jpg

Extras::4) For storing Thumbnails through put(). Example of stream() ...

附加功能::4) 用于通过put(). 流()示例...

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

Hope that it helps someone.

希望它可以帮助某人。

回答by Nikola Gavric

1.) Why is there vvstoragein the url?

1.) 为什么vvstorage在 url 中有?

It is appending that route because your rootfolder inside of your configurationfor S3is set as vvstorage, so whenever you upload to S3all files will be prepended with vvstorage.

它附加该路由,因为您rootconfigurationfor 中的文件夹S3设置为vvstorage,因此每当您上传到S3所有文件时,都会在前面加上vvstorage.

2.) Why random name even when you passed the name of the file?

2.) 即使您传递了文件名,为什么还要随机命名?

Because when using putthe file will get a unique IDgenerated and set as it's file name so no matter what you pass, it won't save the file under the name you wanted. But if you use putFileAsthen you can override the default behaviour of putand pass a name of the file.

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

Hope this clarifies it

希望这能澄清它