PHP操作Amazon S3删除文件夹 正则排除文件不生效问题
结论
Aws\S3\S3Client::deleteMatchingObjects() 支持同时传入前缀和正则做匹配过滤,二者是分层生效的,不存在互斥问题。
方法匹配逻辑
这个方法的过滤分两步执行:
- 服务端前缀过滤:调用S3的ListObjects接口时直接传入你设置的前缀参数,S3服务端只会返回键名以该前缀开头的对象,不会拉取整个存储桶的全量数据
- 客户端正则过滤:SDK拿到服务端返回的对象列表后,会在本地逐个校验对象键是否匹配你传入的正则,只有匹配成功的对象才会被加入待删除队列
你的代码不生效的原因
核心问题是传入的前缀参数错误:
你实际要删除的目录是MY_FOLDER_NAME-finished,但传入的前缀是MY_FOLDER_NAME。S3本身没有原生文件夹概念,所有键都是字符串,前缀匹配是严格的字符串前缀匹配,不是按文件夹名做语义匹配:你传入的MY_FOLDER_NAME作为前缀,会匹配所有以这个字符串开头的键,比如MY_FOLDER_NAME/abc.jpg、MY_FOLDER_NAME-test/123.png,但如果你要精准定位MY_FOLDER_NAME-finished这个目录,前缀必须传MY_FOLDER_NAME-finished/,末尾的斜杠一定要加,否则会匹配到MY_FOLDER_NAME-finished-1、MY_FOLDER_NAME-finished2这类同前缀的非目标路径。
你写的正则/^[^.]+$/本身是符合“匹配不含.的键名”这个需求的,目标目录的占位对象(0字节、键名以/结尾的对象)确实不含.,能被这个正则匹配到,之前没删掉纯粹是前缀不对,没拉到目标对象而已。
修正代码
// 精准指定目标目录前缀,末尾加/避免误匹配 $targetPrefix = 'MY_FOLDER_NAME-finished/'; $this->s3Client->deleteMatchingObjects( $bucket, $targetPrefix, "/^[^.]+$/" );
额外提醒
- 你当前用的正则会匹配所有键名不含
.的对象,除了目录占位对象,还会删掉所有无扩展名的普通文件。如果你的真实需求只是删除目录层级对应的占位对象,建议把正则改成/\/$/,仅匹配以/结尾的目录对象,避免误删文件。 - 正式执行删除前,建议先把删除逻辑替换为遍历打印匹配到的键名,确认匹配范围完全符合预期后再执行删除操作,避免数据误删。
内容的提问来源于stack exchange,提问作者f7n
相关产品推荐
相关产品推荐

