🐡

PHPからS3へのファイルアップロードをLocalStackを使ってやってみる

2022/07/27に公開
1

LocalStackバージョン1.0をリリースしました。
そこで今回ローカル環境からS3にファイルをアップするコードを書いてみた。

環境

  • PHP 7.4.10
  • LocalStack 1.0.1

手元にあったMacに入っていたPHPが古かった

準備

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
  • SERVICESで使うサービスを指定する(今回はS3のみ指定)
  • AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEYの値はなんでも良いです
  • AWS_DEFAULT_REGIONは東京リージョン
  • 永続化の設定とかあるけど今回はなし

Docker起動

$ docker compose up -d --build

以降は起動している前提で書いていきます。

バケット作成

LocalStackのコンテナにAWS CLIも一緒に入っていたのでそこからコマンドでバケットを作成する。

$ 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

s3にファイルアップロードするPHPのコード

パッケージのインストール

AWS SDK for PHPを使いたいのでComposerを使ってインストール

$ composer require aws/aws-sdk-php

PHPのコード

<?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);

// アップロード
$result = $s3->putObject([
    'Bucket' => 'local-test',  // バケット名
    'Key' => 'hello.txt',      // s3のアップロード先
    'Body' => 'hello world!!', // ファイルの内容
]);

echo 'ファイルのURL => ' . $result['ObjectURL'] . PHP_EOL;

// 内容の取得
$result = $s3->getObject([
    'Bucket' => 'local-test',  // バケット名
    'Key' => 'hello.txt',      // s3のアップロード先
]);

echo 'ファイルの内容 => ' . $result['Body'] . PHP_EOL;

大事なところはendpointuse_path_style_endpointです。
LocalStackを使うと実際のS3のURLとは異なるなのでendpointにバケット作成で使ったhttp://localhost:4566を設定する必要がある。

ただし、指定することでendpointhttp://{バケット名}.localhost:4566となり実行すると名前解決できずエラーが発生します。
そこでuse_path_style_endpointtrueを設定することでendpointがパス形式(http://localhost:4566/{バケット名})になり、実行可能になる。

動かしてみる

$ php s3.php
ファイルのURL => http://localhost:4566/local-test/hello.txt
ファイルの内容 => hello world!!

ファイルURLの表示とアップした内容の取得が表示していれば成功です。

確認

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

ファイル名が表示していればOKです。

まとめ

LocalStackを使えば簡単にS3へのアップロードができました。
(ただ、エンドポイントあたりがややこしいです)
他のAWSのサービスも利用可能なので別の機会に触ってみたいと思います。

Discussion