PHP向S3存储桶上传文件报IncalculablePayloadException及ACL设置问题
问题1:IncalculablePayloadException报错原因
- AWS PHP SDK的
putObject方法中,SourceFile参数仅支持本地文件系统的绝对/相对路径,不支持HTTP/HTTPS协议的远程URL。你最初的代码中$file_Path是拼接的当前站点HTTP地址,SDK无法读取远程文件计算payload的校验值和长度,因此抛出该异常。 - 正确做法是填写msk.png在你服务器上的本地路径,比如
$file_Path = __DIR__ . '/msk.png';(假设png文件和当前PHP脚本同目录)。
问题2:改本地路径后上传的文件打开显示AccessDenied的XML原因
你并不是上传了XML文件,而是上传的png对象默认是私有权限,你直接在浏览器访问S3对象的公网URL时,S3返回了AccessDenied的XML响应,浏览器就把这个响应当成了文件内容。你可以在S3控制台查看该对象的大小,如果和本地msk.png一致,就说明上传本身是成功的,只是访问权限不足。
另外你代码里还有两处隐藏问题也可能导致权限报错:
- 你定义了
s3Key和s3Secret变量,但初始化S3Client时没有传入credentials参数,只配置了'profile' => 'default',如果你的运行环境没有配置~/.aws/credentials默认凭证,SDK会拿不到合法的访问密钥,直接导致操作被拒绝。需要补全client配置:
$s3Client = new S3Client([ 'credentials' => [ 'key' => $s3Key, 'secret' => $s3Secret, ], 'region' => $region, 'version' => '2006-03-01', ]);
- 你的
$key参数赋值错误:$key = basename($filepath);里$filepath是站点域名,最终上传的对象名是你的域名,而不是msk.png,应该改为$key = basename($file_Path);。
问题3:putObject配置公共读ACL的方法
直接在putObject的参数数组里加入ACL字段即可,取值为public-read:
$result = $s3Client->putObject([ 'Bucket' => $bucket, 'Key' => $key, 'SourceFile' => $file_Path, 'ACL' => 'public-read', // 新增这行配置公共读权限 ]);
注意:如果你的S3存储桶开启了「阻止所有公共访问」的配置,单独设置对象的公共读ACL会失效,需要先在S3控制台调整存储桶的公共访问策略。
内容的提问来源于stack exchange,提问作者Rom
相关产品推荐
相关产品推荐

