如何将doObjectExist()请求批量处理到Amazon S3?

Cod*_*der 3 php amazon-s3 amazon-web-services

我需要检查S3中是否存在一组密钥,用于大量项目中的每一个.(每组键与大量项目中的一个相关).

我正在使用PHP SDK(v2)

目前我正在呼叫$client->doesObjectExist(BUCKET, $key)每个密钥,这是一个瓶颈(每次呼叫到S3的往返时间).

我更喜欢做类似的$client->doesObjectExist(BUCKET, $batch)地方$batch = array($key1, $key2 ... $keyn),并且客户端检查所有这些密钥然后返回一系列响应(或其他类似的结构).

我遇到过一些 "批量api"的引用,这听起来很有希望,但没有什么具体的.我猜这可能只存在于v1 SDK中.

Jer*_*lom 6

您可以通过利用底层Guzzle库功能,使用AWS SDK for PHP执行并行请求.由于该doesObjectExist方法实际上HeadObject在该引擎盖下进行操作.您可以通过执行以下操作来创建HeadObject命令组:

use Aws\S3\S3Client;
use Guzzle\Service\Exception\CommandTransferException;

function doObjectsExist(S3Client $s3, $bucket, array $objectKeys)
{
    $headObjectCommands = array();
    foreach ($objectKeys as $key) {
        $headObjectCommands[] = $s3->getCommand('HeadObject', array(
            'Bucket' => $bucket,
            'Key'    => $key
        ));
    }

    try {
        $s3->execute($headObjectCommands); // Executes in parallel
        return true;
    } catch (CommandTransferException $e) {
        return false;
    }
}

$s3 = S3Client::factory(array(
    'key'    => 'your_aws_access_key_id',
    'bucket' => 'your_aws_secret_key',
));
$bucket = 'your_bucket_name';
$objectKeys = array('object_key_1', 'object_key_2','object_key_3');

// Returns true only if ALL of the objects exist
echo doObjectsExist($s3, $bucket, $objectKeys) ? 'YES' : 'NO';
Run Code Online (Sandbox Code Playgroud)

如果您想要响应中的数据,除了键是否存在,您可以更改try-catch块来执行类似的操作.

try {
    $executedCommands = $s3->execute($headObjectCommands);
} catch (CommandTransferException $e) {
    $executedCommands = $e->getAllCommands();
}

// Do stuff with the command objects
foreach ($executedCommands as $command) {
    $exists = $command->getResponse()->isSuccessful() ? "YES" : "NO";
    echo "{$command['Bucket']}/{$command['Key']}: {$exists}\n";
}
Run Code Online (Sandbox Code Playgroud)

AWS SDK for PHP用户指南中提到了并行发送命令,但我还要看一下Guzzle批处理文档.