问题 AWS S3 Helper上传文件后如何解锁文件?


我正在使用 官方PHP SDK 同 laravel的官方服务提供商 将图像上传到Amazon S3。图像暂时存储在我的服务器上,上传后应删除。以下是我用来上传和删除的代码。

$temp_path = "/screenshot_temp/testing.png";

$client = AWS::createClient('s3');
$result = $client->putObject(array(
        'Bucket'     => self::$bucketName,
        'Key'        => 'screenshot/testing.png',
        'SourceFile' => $temp_path,
        'ACL'    => 'public-read'
    ));
);

chown($temp_path, 777);
unlink($temp_path);

上传成功。我可以通过链接返回看到我的图像,我可以在亚马逊控制台上看到它。问题是删除失败,并显示以下错误消息:

ErrorException: unlink(... path of my file ...): Permission denied

我确信我的文件权限设置是正确的,我可以删除我的文件与代码部分上传到S3注释。因此,在上传文件期间文件被锁定应该是问题。有没有办法解锁和删除我的文件?


10102
2017-12-30 11:07


起源

bucket对象不是文件


答案:


是的,流上传锁定文件,直到它完成,尝试2中的任何一个,

$client = AWS::createClient('s3');
$fileContent = file_get_contents($temp_path);
$result = $client->putObject(array(
    'Bucket'     => self::$bucketName,
    'Key'        => 'screenshot/testing.png',
    'Body'       => $fileContent,
    'ACL'        => 'public-read'
));
);

unlink($temp_path);

要么

$client = AWS::createClient('s3');
$fileContent = file_get_contents($temp_path);
$result = $client->putObject(array(
    'Bucket'     => self::$bucketName,
    'Key'        => 'screenshot/testing.png',
    'Body'       => $fileContent,
    'ACL'        => 'public-read'
));
);

gc_collect_cycles();
unlink($temp_path);

7
2017-12-30 11:33



首先,我想它应该是 file_get_contents()否则会导致找不到功能。即使我更改为file_get_contents,代码也无法正常工作。功能仍然需要 $fileContent 作为文件路径和返回文件未找到。 - cytsunny
我的坏,:(更正了我的代码。 - Vineesh
不确定第二种方法,但第一种方法适合我。 - cytsunny


当你使用时 SourceFile 选项在 putObject S3Client打开一个文件,但在操作后不会关闭它。

在大多数情况下,你可以解开 $client 和/或 $result 关闭打开的文件。 但 不幸 不是在这种情况下。

使用 Body 选项而不是 SourceFile

// temp file
$file = fopen($temp_path, "r");

// use resource, not a path
$result = $client->putObject(array(
        'Bucket'     => self::$bucketName,
        'Key'        => 'screenshot/testing.png',
        'Body'       => $file,
        'ACL'        => 'public-read'
    ));
);

fclose($file);

unlink($temp_path);

3
2018-01-08 20:12





编辑:我刚刚注意到你的$ temp_path中的字符串以“/”斜杠字符开头。这个开头的斜线通常从网站的根目录开始,你确定这是正确的位置吗?使用PHP中的getcwd()命令找出PHP认为它所在的文件夹。

我知道您认为权限是正确的,但鉴于“权限被拒绝”错误,我仍然认为它告诉您相关的内容。

我看到你正在尝试chown目录,你可能意味着chmod它吗?如果您可以通过SSH连接到服务器并运行此命令,那么您可能会有更多的运气:

chmod -R 777 /(your-website-dir/screenshot_temp

甚至尝试在PHP代码中将“chown”更改为“chmod”。


1
2018-01-03 07:40



这是一个虚假的位置,用于演示目的。出于安全原因,我不会发布实际路径。实际路径不在根目录中,我确信路径正确,因为上传成功。 - cytsunny
好的路径。但是你试过用chmod替换错误的chown命令吗? - Seb
我确信它也是正确的,因为我可以看到当我使用时更改了权限 ls 命令。 - cytsunny


我不是一个PHP人,但我会尝试将那个坏孩子放入流中,然后将流传递给SDK。

这样,您可以显式关闭流,然后删除临时文件。如果您的特定用例允许,您甚至可以完全删除临时文件并仅处理流。

好像 这个SO帖子 可能会让你走上正轨。


1
2018-01-10 01:59



是的,这是其他答案所暗示的方式。我很惊讶亚马逊编写的SDK没有提供关闭流的方法,或者只是默认关闭流..... - cytsunny