EC2にアップロードしたファイルをPHPで受け取ってS3で保存する方法として、s3fsを使ってS3をマウントして使う方法を前に書きました(記事はこちら)が、AWSテクニカルエバンジェリストの堀内さんにこの件についてお聞きしたところ、
「s3fsとかありますけどあんまりお勧めしないですね。動いてたらいいですけど・・・いろんな人の話を総合するとあんまりよくないですね。AWSのAPI経由でS3に保存して、URLで直接S3から表示する方がいいですね。」
という感じで、EC2+PHPからS3を利用するための方向性についてアドバイスをもらったので、実際にそのAWSのAPI(SDK2 for PHP)を使ったS3へのファイル転送を試した結果をまとめてみました。
使用したインスタンスのイメージですが、『Basic 32-bit Amazon Linux AMI 2011.02.1 Beta (AMI Id: ami-300ca731)』を使用しました。また、Amazon EC2 (Amazon Linux) での ApacheとPHP インストールと設定が設定されている状態から行っています。
「s3fsとかありますけどあんまりお勧めしないですね。動いてたらいいですけど・・・いろんな人の話を総合するとあんまりよくないですね。AWSのAPI経由でS3に保存して、URLで直接S3から表示する方がいいですね。」
という感じで、EC2+PHPからS3を利用するための方向性についてアドバイスをもらったので、実際にそのAWSのAPI(SDK2 for PHP)を使ったS3へのファイル転送を試した結果をまとめてみました。
使用したインスタンスのイメージですが、『Basic 32-bit Amazon Linux AMI 2011.02.1 Beta (AMI Id: ami-300ca731)』を使用しました。また、Amazon EC2 (Amazon Linux) での ApacheとPHP インストールと設定が設定されている状態から行っています。
管理者になる
AWS SDK for PHPのインストール及び設定はPEARを使います。管理者権限で行いますので権限を取ります。
$sudo su -
PEARのアップデートとAWS SDK for PHPのインストール
本環境のPEARでは途中インストールが中断しましたので、まずはPEAR自体をアップグレードします。
#pear upgrade pear
次にSDKのインストールに必要なチャネルを登録します。
#pear channel-discover pear.amazonwebservices.com #pear channel-discover guzzlephp.org/pear #pear channel-discover pear.symfony.com
最後にSDKをインストールします。
#pear install aws/sdk
アップロードされたファイルをEC2からAPI経由でS3に転送するPHPのコード
ブラウザのフォームからPOSTされてくる写真などのファイルをS3に転送するPHPのプログラムコードです。
まず、APIを利用するために必要となる環境を定義します。
以下は実際のアップロードのためのコードです。赤字部分を適宜修正してください。
S3を操作するオブジェクトを生成する際のパラメータは次の通りです。
ファイルをS3に転送する際のパラメーターは次の通りです。
まず、APIを利用するために必要となる環境を定義します。
<?php // SDKの読み込み require 'AWSSDKforPHP/aws.phar'; // 利用クラスの定義 use Aws\Common\Aws; use Aws\Common\Enum\Region; use Aws\S3\Enum\CannedAcl; use Aws\S3\Exception\S3Exception; use Guzzle\Http\EntityBody; class FileUploader extends Application { (以下省略)
以下は実際のアップロードのためのコードです。赤字部分を適宜修正してください。
function upload() { try { // S3を操作するためのオブジェクトを生成(リージョンは東京) $s3 = Aws::factory(array('key' => 'AccessKey', 'secret' => 'SecretKey', 'region' => Region::AP_NORTHEAST_1))->get('s3'); $tempFileName = $_FILES['file']['tmp_name']; $tempFileType = $_FILES['file']["type"]; $response = $s3->putObject(array('Bucket' => 'BucketName', 'Key' => 'Directory/FileName', 'Body' => EntityBody::factory(fopen($tempFileName, 'r')), 'ContentType' => $tempFileType, 'StorageClass' => 'STANDARD', 'ServerSideEncryption' => 'AES256', 'ACL' => CannedAcl::PUBLIC_READ)); } catch (S3Exception $e) { }
S3を操作するオブジェクトを生成する際のパラメータは次の通りです。
key
|
アカウントのセキュリティ証明書ページに表示されているアクセスキーIDを指定します。
|
secret |
アカウントのセキュリティ証明書ページのシークレットアクセスキーにある「表示」をクリックすると表示されるキーを指定します。
|
region |
リージョンを指定します。(設定値について)
|
ファイルをS3に転送する際のパラメーターは次の通りです。
Bucket
|
S3に作成されている保存先のバケット名を指定します。
|
Key |
S3に保存する際のファイル名です。ディレクトも含めて記載します。指定されたディレクトリが無い場合は自動的に作成されます。
|
Body |
S3に転送するファイルのパスを指定します。
|
ContentType |
ファイルのContentTypeを指定します。
|
StorageClass |
S3への保存の仕方です。STANDARD、REDUCED_REDUNDANCYがあります。(後者は永続性が低下する代わりに保存料金が安くなります。)
|
ServerSideEncryption |
暗号化して保存する場合に指定します。暗号化しない場合は省略します。
|
ACL |
S3に転送後のファイルの操作権限を指定します。(設定値について)
|
アップロードされたファイルは、例えば画像なら、http://s3-ap-northeast-1.amazonaws.com/BucketName/Directory/FileNameのようにS3から直接表示できます。料金もEC2経由で表示するのとほぼ変わりません。
なお、内部資料などのようにネット上に公開しないファイルの場合は、ACLをPRIVATE_ACCESSなどに設定して、EC2からAPI経由でS3のオブジェクトを取り出して返すことになります。