You must [generate an Access Key](https://developers.cloudflare.com/r2/api/s3/tokens/) before getting started. All examples will utilize `access_key_id` and `access_key_secret` variables which represent the **Access Key ID** and **Secret Access Key** values you generated.



This example uses version 3 of the [aws-sdk-php](https://packagist.org/packages/aws/aws-sdk-php) package. You must pass in the R2 configuration credentials when instantiating your `S3` service client:

Compatibility

Client version `3.337.0` introduced a modification to the default checksum behavior from the client that is currently incompatible with R2 APIs.

To mitigate, users can use `3.336.15` or add the following to their $options:

```php
'request_checksum_calculation' => 'when_required',
'response_checksum_validation' => 'when_required'
```

```php
<?php
require 'vendor/aws/aws-autoloader.php';


$bucket_name        = "sdk-example";
$account_id         = "<accountid>";
$access_key_id      = "<access_key_id>";
$access_key_secret  = "<access_key_secret>";


$credentials = new Aws\Credentials\Credentials($access_key_id, $access_key_secret);


$options = [
    'region' => 'auto',
    'endpoint' => "https://$account_id.r2.cloudflarestorage.com",
    'version' => 'latest',
    'credentials' => $credentials
];


$s3_client = new Aws\S3\S3Client($options);


$contents = $s3_client->listObjectsV2([
    'Bucket' => $bucket_name
]);


var_dump($contents['Contents']);


// array(1) {
//   [0]=>
//   array(5) {
//     ["Key"]=>
//     string(14) "ferriswasm.png"
//     ["LastModified"]=>
//     object(Aws\Api\DateTimeResult)#187 (3) {
//       ["date"]=>
//       string(26) "2022-05-18 17:20:21.670000"
//       ["timezone_type"]=>
//       int(2)
//       ["timezone"]=>
//       string(1) "Z"
//     }
//     ["ETag"]=>
//     string(34) ""eb2b891dc67b81755d2b726d9110af16""
//     ["Size"]=>
//     string(5) "87671"
//     ["StorageClass"]=>
//     string(8) "STANDARD"
//   }
// }


$buckets = $s3_client->listBuckets();


var_dump($buckets['Buckets']);


// array(1) {
//   [0]=>
//   array(2) {
//     ["Name"]=>
//     string(11) "sdk-example"
//     ["CreationDate"]=>
//     object(Aws\Api\DateTimeResult)#212 (3) {
//       ["date"]=>
//       string(26) "2022-05-18 17:19:59.645000"
//       ["timezone_type"]=>
//       int(2)
//       ["timezone"]=>
//       string(1) "Z"
//     }
//   }
// }


?>
```

## Generate presigned URLs

You can also generate presigned links that can be used to share public read or write access to a bucket temporarily.

```php
$cmd = $s3_client->getCommand('GetObject', [
    'Bucket' => $bucket_name,
    'Key' => 'ferriswasm.png'
]);


// The second parameter allows you to determine how long the presigned link is valid.
$request = $s3_client->createPresignedRequest($cmd, '+1 hour');


print_r((string)$request->getUri())
// https://sdk-example.<accountid>.r2.cloudflarestorage.com/ferriswasm.png?X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=<credential>&X-Amz-Date=<timestamp>&X-Amz-SignedHeaders=host&X-Amz-Expires=3600&X-Amz-Signature=<signature>


// You can also create links for operations such as putObject to allow temporary write access to a specific key.
$cmd = $s3_client->getCommand('PutObject', [
    'Bucket' => $bucket_name,
    'Key' => 'ferriswasm.png'
]);


$request = $s3_client->createPresignedRequest($cmd, '+1 hour');


print_r((string)$request->getUri())
```

You can use the link generated by the `putObject` example to upload to the specified bucket and key, until the presigned link expires.

```sh
curl -X PUT https://sdk-example.<accountid>.r2.cloudflarestorage.com/ferriswasm.png?X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=<credential>&X-Amz-Date=<timestamp>&X-Amz-SignedHeaders=host&X-Amz-Expires=3600&X-Amz-Signature=<signature> --data-binary @ferriswasm.png
```
