CakePHPからAWS S3に画像を保存する方法

こんにちは!ぐちです。

Amazon Web Service

CakePHPのDataSourceを用いてS3へ画像を保存する必要があったので試行錯誤した結果を備忘録として残します。超個人的な書き方やあってんの?!という箇所が多数あると思いますがご了承ください。

Cakephp2_AWS_S3_DataSource

下記のプラグインを利用させて頂きました。といいましてもぐちゃぐちゃにしてしまったような気もしています。

Cakephp2_AWS_S3_DataSource

準備

まずは上記のプラグインをプロジェクト配下に持ってきます。

$ cd app/Plugin
$ git clone https://github.com/zaru/Cakephp2_AWS_S3_DataSource.git AmazonWebServices

次にAWS SDK for PHPを取得します。これがいまいちわからなかったのですが上記のプラグインと同じ位置に配置しちゃいました。

AWS SDK for PHP

配置したのは
app/Plugin/AmazonWebServices/Model/Datasource/
です。

そしてプラグインを読み込ませます。

CakePlugin::load('AmazonWebServices');

S3用のDatasourceを定義します。

public $s3 = array(
    'datasource' => 'AmazonWebServices.S3',
    'bucket_name' => ‘YOUR_BUCKET_NAME',
    'key' => ‘YOUR_ACCESS_KEY',
    'secret' => ‘YOUR_SECRET_KEY',
    'default_cache_config' => '',
    'certificate_authority' => false,
    'region' => ‘YOUR_REGION'
);

S3を操作するためのモデルを作成します。

<?php
App::uses('AppModel', 'Model');

class AmazonS3 extends AppModel {
    public $name = 'AmazonS3';
    public $useDbConfig = 's3';
}

コントローラから$this->でモデルを使えるように下記を定義します。

class HogeController extends AppController {
    public $uses = array('AmazonS3');

putできない

Git等に書かれている手順で進めてもどうしてもS3へファイルをputできなかったのでStreamWrapperを使うことにしました。S3関連の処理はまとめておきたかったのとあまりに手を加えて後戻りできなくなるのも嫌(笑)だったのでプラグインのDataSourceをカスタマイズさせて頂きました。zaruさんすいません。。。

public function __construct($config = array(), $autoConnect = true){
    parent::__construct($config);
    $this->S3 = S3Client::factory($config);
    $this->S3->registerStreamWrapper(); // これを追加した
    $this->bucketName = $config['bucket_name'];
}

メソッドを追加

既存のメソッドと同じようにqueryメソッドに分岐とメソッドの定義を追加しました。

public function query($method, $query = array()) {
    switch ($method) {
        case 'makeFolder':
            if (isset($query['0'])) {
                return $this->makeFolder($query['0']);
            }
            break;
        case 'putFile':
            if (isset($query['0']) && isset($query['1'])) {
                return $this->putFile($query['0'], $query['1']);
            }
            break;
        default:
            break;
    }
}

〜 中略 〜

protected function makeFolder($path) {
    mkdir(’s3://YOUR_BACKET_NAME/'.$path, '0604', true);
}

これでs3://というプロトコルを用いてfile_get_contents()などのPHP関数を利用することができるようになりました。

AWSの仕様も知識が深くなくCakePHPのDataSource周りも勉強不足ですのでこれであっているのか非常に不安です。もっともっと勉強しないといけないなと心底感じました。ただ久しぶりに実装を行ったのでとても楽しかったです。やっぱりコーディングし続けないといけないですね!