aws/aws-sdk-php-symfony
Symfony bundle integrating the AWS SDK for PHP. Install via Composer, register AwsBundle, and configure AWS clients/services through Symfony container parameters or env vars, with optional config validation/merging and support for instance profile credentials.
Installation:
composer require aws/aws-sdk-php-symfony
For Symfony 6+ (Flex-compatible), the package auto-registers. For older versions, add to config/bundles.php:
return [
// ...
Aws\Symfony\AwsBundle::class => ['all' => true],
];
First Use Case: Inject the S3 client in a controller/service:
use Aws\S3\S3Client;
class UploadController
{
public function __construct(private S3Client $s3Client) {}
public function upload()
{
$this->s3Client->putObject([
'Bucket' => 'my-bucket',
'Key' => 'file.txt',
'Body' => fopen('file.txt', 'r'),
]);
}
}
Symfony’s autowiring handles the S3Client injection automatically.
Configuration:
Add to .env:
AWS_ACCESS_KEY_ID=your-key
AWS_SECRET_ACCESS_KEY=your-secret
AWS_DEFAULT_REGION=us-east-1
Or use config/packages/aws.yaml:
aws:
version: latest
region: us-west-2
credentials:
key: '%env(AWS_ACCESS_KEY_ID)%'
secret: '%env(AWS_SECRET_ACCESS_KEY)%'
Verify Services:
php bin/console debug:container aws.s3
Output should show the Aws\S3\S3Client service.
Service Injection:
// Controller/Service
public function __construct(
private Aws\DynamoDb\DynamoDbClient $dynamoDb,
private Aws\Sqs\SqsClient $sqs
) {}
Leverage Symfony’s autowiring for all AWS clients (e.g., S3Client, SNSClient).
Dynamic Configuration:
Override per-service settings in config/packages/aws.yaml:
aws:
region: us-east-1
DynamoDb:
region: eu-west-1 # Override for DynamoDB only
Lazy-Loaded Clients: Clients are lazy-loaded by default (since v2.4.0), reducing boot time:
$this->s3Client->listBuckets(); // Loads only when first used
Custom Credentials: Use a service for credentials (e.g., from a secrets manager):
services:
app.aws_credentials:
class: Aws\Credentials\Credentials
arguments: ['%env(DB_KEY)%', '%env(DB_SECRET)%']
aws:
Sqs:
credentials: '@app.aws_credentials'
Instance Profile Credentials (EC2):
aws:
credentials: ~ # Auto-fetches from EC2 metadata
Laravel + Symfony Hybrid Apps:
Use the bundle in a Symfony microservice and share the AWS SDK via a shared container (e.g., symfony/dependency-injection).
// In Laravel, manually create the SDK:
$sdk = new Aws\Sdk([
'region' => 'us-east-1',
'version' => 'latest',
]);
Testing:
Mock AWS clients in tests using Symfony’s Test\MockObject\MockObject:
use Aws\S3\S3Client;
use PHPUnit\Framework\TestCase;
class UploadTest extends TestCase
{
public function testUpload()
{
$mock = $this->createMock(S3Client::class);
$mock->method('putObject')->willReturn(true);
$this->container->set(S3Client::class, $mock);
// Test logic...
}
}
Event-Driven Workflows:
Use AWS SDK events (e.g., Aws\Common\Event\Events) with Symfony’s event dispatcher:
$sdk->register('before', function ($request) {
$this->eventDispatcher->dispatch(new AwsEvent($request));
});
Retry Logic:
Configure retries globally in config/packages/aws.yaml:
aws:
retry:
max_attempts: 3
modes:
- standard
Configuration Merging:
AWS_MERGE_CONFIG=true in .env.~ to omit or ensure uniqueness.Service Aliases:
aws.{service} (e.g., aws.s3) and as the class name (e.g., Aws\S3\S3Client).// Good: Explicit type
public function __construct(private S3Client $s3Client) {}
// Avoid: Magic strings
public function __construct(private ContainerInterface $container) {}
Lazy Loading:
services:
aws.s3:
lazy: false
PHP 8.5+ Features:
Symfony 6+ Deprecations:
config/packages/aws.yaml uses the new services structure:
framework:
secret: '%env(APP_SECRET)%'
aws:
# ... (rest of config)
Missing Services:
php bin/console debug:container aws to list available services.config/bundles.php (Symfony <6) or composer.json (Symfony ≥6).Configuration Errors:
APP_DEBUG=1) and check logs for Aws\Symfony\Exception\ConfigurationException.AWS_MERGE_CONFIG=true to catch misconfigurations early.Credential Issues:
aws sts get-caller-identity --profile your-profile
Performance:
$this->container->get(S3Client::class); // Force initialization
Custom SDK Configuration: Extend the bundle’s configuration by creating a custom compiler pass:
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
class CustomAwsConfigPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
$definition = $container->getDefinition('aws.sdk');
$definition->addMethodCall('configure', [
['custom_key' => 'custom_value']
]);
}
}
Register the pass in services.yaml:
services:
App\DependencyInjection\CustomAwsConfigPass:
tags: [container.compiler_pass]
Middleware: Add custom middleware to the SDK:
$sdk = $this->container->get('aws.sdk');
$sdk->registerMiddleware(new class implements Aws\Common\Middleware\MiddlewareInterface {
public function __invoke($request, callable $next)
{
// Pre-process request
$response = $next($request);
// Post-process response
return $response;
}
});
Testing Helpers: Create a base test case for AWS interactions:
abstract class AwsTestCase extends TestCase
{
protected function getMockClient(string $service): object
{
$mock = $this->createMock("Aws\\{$service}\\{$service}Client");
$mock->method('__call')->willReturn(true);
return $mock;
}
protected function setMockClient(string $service, object $mock)
{
$this->container->set("Aws\\{$service}\\{$service}Client", $mock);
}
}
Environment-Specific Configs: Use Symfony’s environment-aware configuration:
#
How can I help you explore Laravel packages today?