async-aws/s3
AsyncAws S3 is a lightweight, async-friendly AWS S3 API client for PHP. Install via Composer and use it to upload, download, list, and manage buckets and objects with a modern, typed client. Part of the AsyncAws suite.
Installation:
composer require async-aws/s3
Basic Client Initialization:
use AsyncAws\S3\S3Client;
$client = new S3Client([
'region' => 'us-east-1',
'version' => 'latest',
'credentials' => [
'key' => 'YOUR_ACCESS_KEY',
'secret' => 'YOUR_SECRET_KEY',
],
]);
First Use Case: Upload a file to S3:
$result = $client->putObject([
'Bucket' => 'your-bucket-name',
'Key' => 'path/to/file.txt',
'Body' => fopen('local-file.txt', 'r'),
]);
src/Input/ for request objects and src/Result/ for response objects.$client->putObject([
'Bucket' => 'bucket-name',
'Key' => 'file.txt',
'Body' => fopen('local-file.txt', 'r'),
'ACL' => 'public-read', // Optional
]);
$result = $client->getObject([
'Bucket' => 'bucket-name',
'Key' => 'file.txt',
]);
file_put_contents('downloaded-file.txt', $result->getBody()->getContents());
$uploadId = $client->createMultipartUpload([
'Bucket' => 'bucket-name',
'Key' => 'large-file.txt',
]);
$parts = [];
$file = fopen('large-file.txt', 'r');
while (!feof($file)) {
$part = $client->uploadPart([
'Bucket' => 'bucket-name',
'Key' => 'large-file.txt',
'UploadId' => $uploadId,
'Body' => fread($file, 5 * 1024 * 1024), // 5MB chunks
]);
$parts[] = $part;
}
$client->completeMultipartUpload([
'Bucket' => 'bucket-name',
'Key' => 'large-file.txt',
'UploadId' => $uploadId,
'MultipartUpload' => ['Parts' => $parts],
]);
$client->createBucket(['Bucket' => 'new-bucket-name']);
$buckets = $client->listBuckets();
foreach ($buckets->getBuckets() as $bucket) {
echo $bucket->getName();
}
$client->putBucketVersioning([
'Bucket' => 'bucket-name',
'VersioningConfiguration' => ['Status' => 'Enabled'],
]);
$client->putBucketLifecycleConfiguration([
'Bucket' => 'bucket-name',
'LifecycleConfiguration' => [
'Rules' => [
[
'ID' => 'rule1',
'Status' => 'Enabled',
'Filter' => ['Prefix' => 'logs/'],
'Transitions' => [
['Days' => 30, 'StorageClass' => 'GLACIER'],
],
],
],
],
]);
use AsyncAws\Core\Promise\Promise;
$promise = $client->putObjectAsync([
'Bucket' => 'bucket-name',
'Key' => 'file.txt',
'Body' => fopen('file.txt', 'r'),
]);
$promise->then(function ($result) {
echo "Uploaded successfully!";
})->catch(function ($exception) {
echo "Upload failed: " . $exception->getMessage();
});
Service Provider Setup:
use AsyncAws\S3\S3Client;
use Illuminate\Support\ServiceProvider;
class S3ServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->singleton(S3Client::class, function ($app) {
return new S3Client([
'region' => config('aws.region'),
'credentials' => [
'key' => config('aws.key'),
'secret' => config('aws.secret'),
],
]);
});
}
}
Facade for Convenience:
// config/aws.php
return [
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
];
// app/Providers/AppServiceProvider.php
use Illuminate\Support\Facades\Facade;
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
Facade::register('S3', function () {
return app(S3Client::class);
});
}
}
Usage in Controllers:
use Illuminate\Support\Facades\S3;
public function upload()
{
$result = S3::putObject([
'Bucket' => 'my-bucket',
'Key' => 'uploaded-file.jpg',
'Body' => fopen('file.jpg', 'r'),
]);
return response()->json(['success' => true]);
}
try {
$client->putObject([...]);
} catch (\AsyncAws\Core\Exception\AwsException $e) {
// Handle AWS-specific errors
if ($e->getAwsErrorCode() === 'AccessDenied') {
// Handle access denied
}
} catch (\RuntimeException $e) {
// Handle runtime errors
}
$paginator = $client->getPaginator('listObjectsV2', [
'Bucket' => 'bucket-name',
]);
foreach ($paginator as $page) {
foreach ($page->getContents() as $object) {
echo $object->getKey();
}
}
Region Configuration:
region is correctly set, especially for directory buckets or regional endpoints. Some regions (e.g., us-east-1) do not require a LocationConstraint.us-west-2:
$client = new S3Client([
'region' => 'us-west-2',
'endpoint' => 's3.us-west-2.amazonaws.com',
]);
Path vs. Virtual Hosted-Style Endpoints:
https://bucket-name.s3.amazonaws.com).https://s3.amazonaws.com/bucket-name), set:
$client = new S3Client([
's3PathStyleEndpoint' => true,
]);
Bucket Naming:
#, ?).Metadata Handling:
x-amz-meta-:
$client->putObject([
'Bucket' => 'bucket-name',
'Key' => 'file.txt',
'Metadata' => [
'x-amz-meta-custom-key' => 'value', // Correct
'CustomKey' => 'value', // Incorrect (will be prefixed internally)
],
]);
Checksum Algorithms:
CRC64, SHA-512) are supported but require explicit configuration:
$client->putObject([
'Bucket' => 'bucket-name',
'Key' => 'file.txt',
'Body' => fopen('file.txt', 'r'),
'ChecksumAlgorithm' => 'CRC64', // Optional
]);
Async Operations:
Promise; ensure you handle them properly:
$promise = $client->putObjectAsync([...]);
$result = $promise->wait(); // Blocks until completion
// OR
How can I help you explore Laravel packages today?