【FuelPHP】FuelPHPからAWS S3へ画像アップロードを試してみる。

2013.08.26

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

前回はFuelPHPでs3のバケット情報を取得してみたので、今回はs3へファイルをアップロードを試してみようと思います。

アジェンダ

  • 実行環境
  • S3のパッケージをインストール
  • ファイル準備
  • 動作確認

実行環境

  • Win 7
  • PHP 5.3.3+
  • FuelPHP 1.6

S3に画像アップロード用のバケットを作成しておいてください。今回は[hogeバケット]内に[imgフォルダ]を作成し、[imgフォルダ]内に画像を格納します。

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

以下からパッケージをダウンロードします。

danharper/fuel-s3

ファイルの設置場所は[/fuel/packages/s3/]に設置します。

パッケージの設定ファイルにAWS情報を記述

ダウンロードしたパッケージの[/fuel/packages/s3/config/s3.php]をコピーして、
[/fuel/app/config/s3.php]に格納し、 アクセスキー、シークレットキー、エンドポイントを記述します。

<?php
return array(
    'access_key'  => 'アクセスキーを記述',
    'secret_key'  => 'シークレットキーを記述',
    'use_ssl'     => false,
    'endpoint'    => 'エンドポイント記述',

	/**
	 * Possible Values:
	 * - ACL_PRIVATE
	 * - ACL_PUBLIC_READ
	 * - ACL_PUBLIC_READ_WRITE
	 * - ACL_AUTHENTICATED_READ
	 */
	'default_acl' => 'ACL_PRIVATE',
);

パッケージの読み込みの設定

パッケージ側の設定はできました。次にFuelPHP側でパッケージを読み込む設定をします。
always_loadpackagesに読み込むパッケージの指定をします。

/fuel/app/config/config.php

<?php
return array(	
	
	//上記割愛します。
	
	'always_load'  => array(
		 'packages'  => array(
		    's3',
		 ),	
	),

);

上記でパッケージの設定と読み込みが完了です。

ファイル準備

controller側の設定

controllerディレクトリ内にs3upload.phpファイルを作成します。

[/fuel/app/classes/controller/s3upload]

<?php

class Controller_S3upload extends Controller
{
    public function action_index()
    {
        //viewへ画像アップロード画面を指定
        return Response::forge(View::forge('s3upload/index'));
    }

    public function post_upload()
    {
        $config = array(
            //アップロードする画像の格納先を指定
            'path'  => DOCROOT.'../temp',
            'overwrite' => true,
            //アップロードするファイル名をランダム文字に変更
            'randomize'     => true,
            //アップロードの許可をするファイルの拡張子指定
            'ext_whitelist' => array(
                'img',
                'jpg',
                'jpeg',
                'gif',
                'png'
            ),
        );

        // $confignの設定をもとにファイルの検証をする。
        Upload::process($config);

        // ファイルアップロード検証
        if (Upload::is_valid())
        {
            // 画像アップロード成功の場合
            // 設定を元に保存
            Upload::save(0);
        }

        // 画像アップロード失敗の場合
        foreach (Upload::get_errors() as $file)
        {
            //エラーメッセージの取得
            $error = $file['errors']['0']['message'];

            //viewへエラー画面を指定
            $view = View::forge('s3upload/error');
            $view->set('error', $error);

            //エラーの場合
            return Response::forge($view);
        }

        // 画像アップロード成功の場合
        foreach (Upload::get_files() as $file)
        {
            $thumbs     = array();
            //エンドポイントを指定
            $endpoint = 'XXXXXXXXX';
            //バケット名の指定
            $bucketName = 'XXXXXXXXX';
            //アップロード画像パス
            $input = S3::inputFile($file['saved_to'].$file['saved_as']);
            //S3の指定バケットにアップロード
            S3::putObject($input, $bucketName , 'img/'.$file['saved_as'], 'ACL_PUBLIC_READ');
            //指定格納先にアップロードした画像を一旦削除
            File::delete($file['saved_to'].$file['saved_as']);

            //確認用にS3の指定バケットにアップロードした情報を取得
            if (($contents =S3::getBucket($bucketName, $prefix = 'img'))){
                foreach ($contents as $object) {
                    //最初以外
                    if ($object !== reset($contents)) {
                        //確認用に画像のURLを格納
                        array_push($thumbs , 'https://'.$endpoint.'/'.$bucketName.'/'.$object['name']);
                    };
                };
            }

            //viewへ成功画面を指定
            $view = View::forge('s3upload/success');
            $view->set('success', $thumbs);

            return Response::forge($view);
        }

    }
}

Views側の設定

Viewsディレクトリにs3uploadディレクトリを作成します(/fuel/app/views/s3upload)配下に以下の三つのファイルを格納します。

  • index.php(画像アップロード用のトップ画面)
  • error.php(画像アップロードエラー画面)
  • success.php(画像アップロード成功画面)

画像アップロード用のトップ画面

/fuel/app/views/s3upload/index.php

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>Sample S3 File Uplaodk</title>
	<?php echo Asset::css('bootstrap.css'); ?>
    <style> body {padding-top: 60px;}</style>
    <!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
    <!--[if lt IE 9]>
    <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
    <![endif]-->
</head>
<body>

<!-- navbar -->
<div class="navbar navbar-inverse navbar-fixed-top">
    <div class="navbar-inner">
        <div class="container">
            <a class="brand" href="/">AWS S3</a>
        </div>
    </div>
</div>
<!-- /navbar -->

<!-- container -->
<div class="container-fluid">
    <div class="row-fluid">
        <form id="addForm"  method="post" action="/s3upload/upload" enctype="multipart/form-data">
                <fieldset>
                    <legend>S3へ 画像をアップロード</legend>
                    <label>画像を選択してください。</label>
                    <input type="file" id="uploadFile" name="uploadFile" placeholder="ファイルを選択">
                    <input type="submit" value="S3にアップロード" class="btn btn-primary"/>
                </fieldset>
            </form>
        </div>
    </div>
</div>
<!-- /container -->

</body>
</html>

28行目でs3uploadコントローラーのuploadメソッドを指定しています。

画像アップロードエラー画面

/fuel/app/views/s3upload/error.php

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>Error | Sample S3 File Uplaodk</title>
	<?php echo Asset::css('bootstrap.css'); ?>
    <style> body {padding-top: 60px;}</style>
    <!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
    <!--[if lt IE 9]>
    <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
    <![endif]-->
</head>
<body>

<!-- navbar -->
<div class="navbar navbar-inverse navbar-fixed-top">
    <div class="navbar-inner">
        <div class="container">
            <a class="brand" href="/">AWS S3</a>
        </div>
    </div>
</div>
<!-- /navbar -->

<!-- container -->
<div class="container-fluid">
    <div class="row-fluid">
        <section>
            <div class="page-header">
                <h1>画像のアップロード失敗</h1>
            </div>
            <div class="alert alert-error alert-block">
                <button type="button" class="close" data-dismiss="alert">×</button>
                <h4>エラー内容</h4>
                <p><?php echo $error; ?></p>
            </div>
            <div class="btn-group">
                <a href="/s3upload/" class="btn">戻る</a>
            </div>
        </section>
    </div>
</div>
<!-- /container -->



</body>
</html>

画像アップロード成功画面

/fuel/app/views/s3upload/success.php

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>Success | Sample S3 File Uplaodk</title>
	<?php echo Asset::css('bootstrap.css'); ?>
    <style> body {padding-top: 60px;}</style>
    <!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
    <!--[if lt IE 9]>
    <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
    <![endif]-->
</head>
<body>

<!-- navbar -->
<div class="navbar navbar-inverse navbar-fixed-top">
    <div class="navbar-inner">
        <div class="container">
            <a class="brand" href="/">AWS S3</a>
        </div>
    </div>
</div>
<!-- /navbar -->

<!-- container -->
<div class="container-fluid">
    <div class="row-fluid">
        <section>
            <div class="page-header">
                <h1>画像のアップロード成功</h1>
            </div>

            <div class="row-fluid">
                <ul class="thumbnails">
                    <?php
                    foreach ($success as $key => $value){
                      echo '<li><img src="'.$value.'" alt="sample" width="100px"></li>';
                    }
                    ?>
                </ul>
            </div>

            <div class="btn-group">
                <a href="/s3upload/" class="btn">戻る</a>
            </div>

        </section>
    </div>
</div>
<!-- /container -->

</body>
</html>

動作確認

それでは実際に動作するか確認してみます。ブラウザ側からhttp://XXXXXXXXX/s3upload/にアクセスすると、画像アップロード画面が表示されます。

img-fuelphp-upload-001

ローカルの画像ファイルを指定しないで[S3にアップロード]をクリックするとエラー画面とエラーメッセージが表示されました。

img-fuelphp-upload-002

ローカルの画像ファイルを指定して[S3にアップロード]し、正常にアップロードができると画像のアップロード成功画面と現在指定バケットにある画像を表示できました。

img-fuelphp-upload-003

FuelPHPのパッケージを利用してS3に画像をアップロードするのを試してみました。
その他にもawsサービス用パッケージが公開されているので今後試してみたいと思います。

参考サイト