2013年1月22日火曜日

AWS SDK2 for PHPを使ってS3にファイルをアップロードする

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  インストールと設定が設定されている状態から行っています。

管理者になる

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を利用するために必要となる環境を定義します。
<?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のオブジェクトを取り出して返すことになります。


Related Posts Plugin for WordPress, Blogger...