如果给定一个不存在的键,S3Client-> GetObject()永远不会返回或抛出异常

AWS S3Client->getObject() never returns and never throws an exception if I request a key that doesn't exist. I suspect that other S3Client methods have the same problem when given a non-existent key.

However, if I configure the S3Client with 'debug' => true, it will throw Aws\S3\Exception\S3Exception when the file is not found, which is acceptable.

Here is a test case I wrote:

protected function _test_s3_client_get($unit, $key) {
    $provider = CredentialProvider::ini(NULL, APPPATH . 'config/aws.ini');
    $provider = CredentialProvider::memoize($provider);
    $client = new S3Client([
        'region' => 'us-east-1',
        'version' => '2006-03-01',
        'credentials' => $provider,
        // 'debug' => ['logfn' => [$this, '_noop']]
        // 'debug' => true,
    ]);
    try {
        $result = $client->getObject(array(
            'Bucket' => 'mybucket',
            'Key'=> $key,
            ));
    } catch (S3Exception $e) {
        error_log($e);
    }
    $unit->run(isset($result['Body']), true, "Got $key");
}

If 'debug' => true, the S3Client dumps a huge amount of data in the response regardless of whether or not it found the file. As a workaround, I can set the debug option to call an empty function with the debug output. Nevertheless, this does not look like a permanent solution.

Has anyone else encountered this problem? Is there a better workaround?

We use "aws/aws-sdk-php": "2.8.22" and we have exception NoSuchKeyException in such cases. Here our code:

private function fileExists($bucket, $key)
{
    try {
        $o = $this->s3->getObject([
            'Bucket' => $bucket,
            'Key' => $key,
        ]);
        return $o;
    } catch (\Aws\S3\Exception\NoSuchKeyException $e) {
        return false;
    }
}

The only one difference in "aws/aws-sdk-php" "3.20.13" is that it throws not NoSuchKeyException but Aws\S3\Exception\S3Exception.

Btw, check your bucket policy. My policy:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "ACZ",
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:DeleteObject"
            ],
            "Resource": "arn:aws:s3:::my.own.bucket/*"
        }
    ]
}

You can check whether the key (filename) exist or not using this function before you do any kind of operation.

$doesFileExist = $client->doesObjectExist($bucket, $key);

This will True or False