使用AWS SDK PHP 3.x获取S3存储桶最新修改对象
使用AWS SDK for PHP 3.x获取S3存储桶最新对象的解决方案
先修正StartAfter参数问题
你当前用strtotime('-5 minutes')作为StartAfter的值是错误的,这个参数接受的是**对象的键(Key)**而非时间戳。如果要筛选最近5分钟修改的对象,得在获取结果后通过LastModified字段过滤,不能用StartAfter实现。
问题1:按最后修改时间排序
S3的ListObjectsV2接口默认按对象键的字典序返回结果,不会自动按修改时间排序。你需要在获取符合条件的对象后,用PHP的usort函数手动排序:
// 获取对象列表 $res = $S3Client->ListObjectsV2([ 'Bucket' => 'my-bucket', 'Prefix' => 'objects/' ]); $objects = $res['Contents']; // 按LastModified倒序排序(最新的在前) usort($objects, function($a, $b) { return $b['LastModified'] <=> $a['LastModified']; });
问题2:排除GLACIER存储类的对象
每个返回的对象包含StorageClass字段,你可以通过数组过滤排除掉存储类为GLACIER(若需要排除其他归档类存储,比如GLACIER_IR、DEEP_ARCHIVE,可自行补充)的对象:
// 过滤掉GLACIER存储类的对象 $filteredObjects = array_filter($objects, function($obj) { return $obj['StorageClass'] !== 'GLACIER'; });
问题3:获取对象标签和元数据
要在ListObjectsV2请求中获取标签和元数据,需要添加OptionalObjectAttributes参数,指定要返回的属性为Tags和Metadata。修改后的请求代码如下:
$res = $S3Client->ListObjectsV2([ 'Bucket' => 'my-bucket', 'Prefix' => 'objects/', 'OptionalObjectAttributes' => ['Tags', 'Metadata'] ]);
请求返回后,每个对象的Tags字段会包含标签键值对,Metadata字段会包含自定义元数据。
整合所有需求的完整代码
$S3Client = new Aws\S3\S3Client([ 'version' => 'latest', 'region' => 'eu-west-3', 'credentials' => [ 'key' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx', 'secret' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx', ] ]); $startTime = new DateTime('-5 minutes'); // 获取带标签和元数据的对象列表 $res = $S3Client->ListObjectsV2([ 'Bucket' => 'my-bucket', 'Prefix' => 'objects/', 'OptionalObjectAttributes' => ['Tags', 'Metadata'] ]); $objects = $res['Contents']; // 1. 排除GLACIER存储类对象;2. 筛选最近5分钟修改的对象 $filteredObjects = array_filter($objects, function($obj) use ($startTime) { return $obj['StorageClass'] !== 'GLACIER' && $obj['LastModified'] >= $startTime; }); // 按最后修改时间倒序排序 usort($filteredObjects, function($a, $b) { return $b['LastModified'] <=> $a['LastModified']; }); // 处理结果,比如取最新的第一个对象 if (!empty($filteredObjects)) { $latestObject = reset($filteredObjects); // 输出标签和元数据示例 print_r($latestObject['Tags']); print_r($latestObject['Metadata']); }
注意事项
- 如果存储桶中有大量对象,
ListObjectsV2会分页返回结果,需要通过NextContinuationToken循环获取所有页的数据,避免遗漏。 - 若需要排除所有归档类存储,可修改过滤条件为:
!in_array($obj['StorageClass'], ['GLACIER', 'GLACIER_IR', 'DEEP_ARCHIVE'])
内容的提问来源于stack exchange,提问作者icalvete
相关产品推荐
相关产品推荐

