iTranslated by AI
Uploading Files to S3 from PHP Using LocalStack
LocalStack has released version 1.0.
So, I decided to write some code to upload files to S3 from a local environment.
Environment
- PHP 7.4.10
- LocalStack 1.0.1
The PHP version on the Mac I had on hand was old.
Preparation
Contents of docker-compose.yml
version: '3'
services:
localstack:
image: localstack/localstack:1.0.1
ports:
- 4566:4566
environment:
- SERVICES=s3
- AWS_ACCESS_KEY_ID=dummy
- AWS_SECRET_ACCESS_KEY=dummy
- AWS_DEFAULT_REGION=ap-northeast-1
- Specify the services to use in
SERVICES(only S3 is specified this time) - The values for
AWS_ACCESS_KEY_IDandAWS_SECRET_ACCESS_KEYcan be anything -
AWS_DEFAULT_REGIONis the Tokyo region - There are settings for persistence and such, but none this time
Docker Startup
$ docker compose up -d --build
From here on, I will proceed assuming it is already running.
Bucket Creation
Since the AWS CLI was included in the LocalStack container, I'll use it to create a bucket via command.
$ docker compose exec localstack aws --endpoint-url=http://localhost:4566 s3 ls s3://
$ docker compose exec localstack aws --endpoint-url=http://localhost:4566 s3 mb s3://local-test
make_bucket: local-test
$ docker compose exec localstack aws --endpoint-url=http://localhost:4566 s3 ls s3://
2020-10-11 21:47:34 local-test
PHP Code to Upload Files to S3
Installing Packages
I want to use the AWS SDK for PHP, so I'll install it using Composer.
$ composer require aws/aws-sdk-php
PHP Code
<?php
require_once 'vendor/autoload.php';
use Aws\S3\S3Client;
$config = [
'credentials' => [
'key' => 'dummy',
'secret' => 'dummy',
],
'region' => 'ap-northeast-1',
'version' => 'latest',
'endpoint' => 'http://localhost:4566',
'use_path_style_endpoint' => true,
];
$s3 = new S3Client($config);
// Upload
$result = $s3->putObject([
'Bucket' => 'local-test', // Bucket name
'Key' => 'hello.txt', // S3 upload destination
'Body' => 'hello world!!', // File content
]);
echo 'File URL => ' . $result['ObjectURL'] . PHP_EOL;
// Get content
$result = $s3->getObject([
'Bucket' => 'local-test', // Bucket name
'Key' => 'hello.txt', // S3 upload destination
]);
echo 'File content => ' . $result['Body'] . PHP_EOL;
The important parts are endpoint and use_path_style_endpoint.
When using LocalStack, the URL is different from the actual S3 URL, so you need to set endpoint to http://localhost:4566, which was used for bucket creation.
However, simply specifying this will make the endpoint something like http://{bucket-name}.localhost:4566, resulting in a name resolution error when executed.
By setting use_path_style_endpoint to true, the endpoint becomes a path-style format (http://localhost:4566/{bucket-name}), making it executable.
Try it out
$ php s3.php
File URL => http://localhost:4566/local-test/hello.txt
File content => hello world!!
If the file URL and the retrieved uploaded content are displayed, it's a success.
Verification
Let's check if the file was uploaded using the AWS CLI.
$ docker compose exec localstack aws --endpoint-url=http://localhost:4566 s3 ls s3://local-test
2020-10-11 23:49:33 13 hello.txt
If the filename is displayed, it's OK.
Summary
I was able to easily upload to S3 using LocalStack.
(However, the endpoint part is a bit tricky.)
Since other AWS services are also available, I'd like to try them out on another occasion.
Discussion
ここで使っているコードをgithubに置いてみた