php - Laravel S3 图片上传会自动创建一个文件名的文件夹

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

我正在使用 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;
}

}

我在 Controller 中调用辅助方法,如下所示:

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

在辅助方法的 $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"

没有得到任何解释为什么会这样。任何线索将不胜感激。

桶名 = vvstorage
我模仿的文件夹 = instant_gifs

最佳答案

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

希望对大家有所帮助。

关于php - Laravel S3 图片上传会自动创建一个文件名的文件夹,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48783020/

相关文章:

php - Laravel Eloquent orderBy 日期字段不返回所有值

laravel - SQLSTATE[23000] : Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails Laravel

php - 获取有帖子的用户

laravel - 使用 Eloquent 手动注入(inject)模型关系

php - 使用 UUID 作为 Laravel 5 的主键

mysql - Laravel 数组到多条记录的字符串转换

php - 为什么注册后数据库没有返回用户的数据?

php - 无法使用Google PHP客户端库通过YouTube API设置水印

javascript - JS函数将空字符串传递回php,但有一个值?

php - 混合 newrelic 代理 PHP + Node