3
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

AWS S3でPHP+javascript でブラウザからアップロードするサンプル

Last updated at Posted at 2018-05-06

なぜこれを作ったのか?

  • 30MB以上のファイルを数多くアップロードする案件があって、サーバ経由でS3にファイルを送るとサーバの負荷がかかる。それを減らすためにブラウザとS3の間で直接通信をする方法を選んだ。
  • ユーザがアップロードするファイルサイズは 10MB ~ 100MB くらいの幅があると考えられる。
  • 今後の案件で 500MB くらいのファイルサイズもあるかも。

S3 ファイルサイズ要件

調べて分かったこと

  • javascript用のSDKを使う方法と、もう一つは、php用のSDKを使ってURLを作成してからjavascriptで送信する方法がある。
  • javascript用のSDKを使う場合、evaporate.js というライブラリがあるようです。
  • php用のSDKを使う場合、phpでURLを発行してjavascriptでS3へマルチパートアップロードをする。この場合は、完了処理のときにPHPで一括してETagを取得する。
  • マルチパートアップロードでアップロード途中のファイルはS3の管理画面上に表示されない。そのため、アップロードに失敗し(中止処理もおこなわれなかっ)たファイルはライフサイクルで削除する設定が必要。※削除する設定をしないで放っておくと見えないまま課金されますので注意してください。

案件で node.js を使っていないので、PHP(署名) + ブラウザのjavascriptで送信という処理を選択しました。

動作確認環境

  • サーバ: AWS ではない CentOS7 環境
  • PHP 7.2
  • aws-sdk-php: 3.52
  • signature_version: v4

Github

こちらにすべてのソースコードを置いてます。
https://github.com/gold1/aws_s3_upload_sample

インストール

$ git clone https://github.com/gold1/aws_s3_upload_sample.git
$ cd aws_s3_upload_sample
$ mkdir download
$ chmod 777 download
$ composer install

config.php にAWSのIAMのキーとバケット名を指定してください。

$config = array(
    'key'     => '',
    'secret'  => '',
    'bucket'  => '',
);

S3 のバケットのCORSの設定を変更して、ブラウザからアップロードできるようにしてください。

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>POST</AllowedMethod>
    <AllowedMethod>PUT</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

S3のバケットのライフサイクルの設定で失敗したマルチパートアップロードを一定期間後に削除するようにしてください。

不完全なマルチパートアップロードをクリーンアップする
次の後: 3 Days アップロード開始からの日数 

Apache でアクセス

test1.html : ブラウザからアップロードするサンプル
test2.html : ブラウザからマルチパートアップロードするサンプル
server3.php : PHPでアップロードするサンプル

ソースファイルの補足

  • マルチパートアップロード後に listParts() という関数で ETag を取得しています。
  • このサンプルは、マルチパートアップロードのファイルサイズが200MBくらいでエラーになるバグが残っています(未解決)。test1.html の通常のアップロードのサンプルは800MBで問題なく動作しました。

参考

3
7
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?