更新时间:2026-06-30 GMT+08:00
批量下载对象
您可以通过以下方式批量下载对象:
示例代码
本示例用于批量下载OBS桶中的对象到本地目录。您可以通过列举满足前缀条件的对象, 再以指定并发数并发下载,文件按原Key结构保存到本地目录,适用于批量导出、离线备份等场景。
<?php
// 本示例用于批量下载OBS桶中的对象到本地目录。您可以通过列举满足前缀条件的对象, 再以指定并发数并发下载,文件按原Key结构保存到本地目录,适用于批量导出、离线备份等场景。
// 引入依赖库
require 'vendor/autoload.php';
// 使用源码安装时引入SDK代码库
// require 'obs-autoloader.php';
// 声明命名空间
use Obs\ObsClient;
// 创建ObsClient实例
$obsClient = new ObsClient ( [
//推荐通过环境变量获取AKSK,这里也可以使用其他外部引入方式传入,如果使用硬编码可能会存在泄露风险。
//您可以登录访问管理控制台获取访问密钥AK/SK,获取方式请参见https://support.huaweicloud.com/intl/zh-cn/usermanual-ca/ca_01_0003.html
'key' => getenv('ACCESS_KEY_ID'),
'secret' => getenv('SECRET_ACCESS_KEY'),
// endpoint填写Bucket对应的Endpoint, 此处以中国-香港为例,其他地区请按实际情况填写。
'endpoint' => "obs.ap-southeast-1.myhuaweicloud.com",
'signature' => 'obs'
] );
$bucketName = 'bucketname';
$localDir = '/tmp/download-dir';
$keyPrefix = 'backup/';
$concurrency = 5;
// 列举满足前缀的对象
$isTruncated = true;
$marker = null;
$objectsToDownload = [];
while ($isTruncated) {
$resp = $obsClient->listObjects ( [
'Bucket' => $bucketName,
'Prefix' => $keyPrefix,
'Marker' => $marker,
// MaxKeys指定每页返回的最大对象数,默认值1000,取值范围1~1000
'MaxKeys' => 1000
] );
if (!empty($resp['Contents'])) {
foreach ($resp['Contents'] as $content) {
$objectsToDownload[] = ['Key' => $content['Key']];
}
}
$isTruncated = $resp['IsTruncated'];
$marker = $resp['NextMarker'];
}
printf("Found %d objects to download\n\n", count($objectsToDownload));
// 并发下载对象,按原Key结构保存到本地目录
// 生产环境建议增加重试机制,避免网络波动或临时故障导致数据不完整
$successCount = 0;
$failCount = 0;
$promiseGenerator = function () use ($obsClient, $bucketName, $localDir, $objectsToDownload, &$successCount, &$failCount) {
foreach ($objectsToDownload as $object) {
$localPath = $localDir . '/' . $object['Key'];
// 路径遍历防护:检测Key中是否包含..以防止目录穿越
if (strpos($object['Key'], '..') !== false) {
printf("SkipUnsafeKey: Key:%s contains path traversal\n", $object['Key']);
$failCount++;
continue;
}
$localDirPath = dirname($localPath);
if (!is_dir($localDirPath)) {
mkdir($localDirPath, 0755, true);
}
yield $obsClient->getObjectAsync ( [
'Bucket' => $bucketName,
'Key' => $object['Key'],
'SaveAsFilepath' => $localPath
], function ($exception, $resp) use ($object, &$successCount, &$failCount) {
if ($exception === null) {
printf ( "Key:%s, ETag:%s, Size:%s\n", $object['Key'], $resp['ETag'], $resp['ContentLength'] );
$successCount++;
} else {
printf ( "DownloadFailed: Key:%s, Status:%d, Message:%s\n", $object['Key'], $exception->getStatusCode(), $exception->getExceptionMessage() );
$failCount++;
}
} );
}
};
$eachPromise = new EachPromise($promiseGenerator(), [
'concurrency' => $concurrency
]);
$eachPromise->promise()->wait();
printf("\nResult: success=%d, fail=%d\n", $successCount, $failCount); 父主题: 下载对象