phpでlocalstackのs3にファイルをアップロード
AWS周りのものをローカルで開発する場合 localstack を使うと便利だというのを聞いたので試してみました。
localstackは、GUIはあまり提供されていない用で、主にawscliコマンドを使います。
s3にファイルをアップロードしたい場合は、 --endpoint-url=http://localhost:4572
を付けてあげてアップロード先を変えることができます。
試しに awscli で test というバケットを作ってファイルをアップロードしてみます。
$ aws --endpoint-url=http://localhost:4572 s3 mb s3://test make_bucket: test $ aws --endpoint-url=http://localhost:4572 s3 ls s3:// 2006-02-04 01:45:09 test $ touch hoge.txt $ aws --endpoint-url=http://localhost:4572 s3 cp hoge.txt s3://test/hoge.txt upload: ./hoge.txt to s3://test/hoge.txt $ aws --endpoint-url=http://localhost:4572 s3 ls s3://test/ 2017-12-08 20:00:00 0 hoge.txt
localstack上のs3にファイルがアップロードされていることが確認できます。
phpを使ってlocalstackのs3にファイルをアップロードしてみます。
awscliのときと同様に、endpointを localstack のs3用エンドポイントを指定してみます。
aws-sdk-php は composer を使って入れてます。
put.php
<?php require_once 'vendor/autoload.php'; use Aws\S3\S3Client as S3Client; $s3 = S3Client::factory(array( 'endpoint' => 'http://localhost:4572', 'credentials' => array( 'key' => '', 'secret' => '', ), 'version' => 'latest' )); $pamans = array( 'Bucket' => 'test', 'Key' => 'hello.txt', 'Body' => 'Hello World', 'CacheControl' => 'max-age=1', ); $s3->putObject($pamans);
実行してみるとエラーが出ます。
Could not resolve host: test.localhost [url] http://test.localhost:4572/hello.txt
hostsが解決できないようなので、/etc/hosts
に
127.0.0.1 test.localhost
を追記します。
再度実行してみるとエラーが出ずに終了し、ファイルが作られていることが確認できました。
$ php put.php $ aws --endpoint-url=http://localhost:4572 s3 ls s3://test/ 2017-12-08 21:00:00 11 hello.txt
javascriptやgoを使う方法を参考にしていると
- s3ForcePathStyle
- endpoint
のオプションを設定してあげればいいと出るのですが、 aws-sdk-php には s3ForcePathStyle
というオプションが無いです。
s3ForcePathStyle
というオプションを設定しないでアップロードしようとすると、先ほどのエラーにも出てましたが、s3バケット名.localhost:4572
となり、hostsが解決できなくなってしまいます。
php と localstack を使って開発したい場合は hosts を書いてあげて localstack が提供する各URLを指定してあげないといけなさそうです。
追記
コメントで指摘頂いた通り、PHPでは use_path_style_endpoint
があり、そちらのオプションを有効にすることで hosts
を設定すること無くテストすることができました。
id:imunew さん、ご指摘ありがとうございます。
put.php を下記の様に 'use_path_style_endpoint' => true
とオプションを追加することでhostsの設定をすることなくテストが可能になりました。
<?php require_once 'vendor/autoload.php'; use Aws\S3\S3Client as S3Client; $s3 = S3Client::factory(array( 'endpoint' => 'http://localhost:4572', 'credentials' => array( 'key' => '', 'secret' => '', ), 'version' => 'latest', 'use_path_style_endpoint' => true )); $pamans = array( 'Bucket' => 'test', 'Key' => 'hello.txt', 'Body' => 'Hello World', 'CacheControl' => 'max-age=1', ); $s3->putObject($pamans);
参考
Testable Lambda: Working Effectively with Legacy Lambda // Speaker Deck
Testable Lambda|AWS Summit Tokyo 2017 - YouTube