1. Home
  2. PHP
  3. CakePHP
  4. CakePHPにAWS SDK for PHPを導入しS3のファイル操作を行う

CakePHPにAWS SDK for PHPを導入しS3のファイル操作を行う

  • 公開日
  • カテゴリ:CakePHP
  • タグ:PHP,AWS,S3,CakePHP,Component,SDK
CakePHPにAWS SDK for PHPを導入しS3のファイル操作を行う

PHP から AWS S3 を操作するには専用の SDK である「AWS SDK for PHP 」が用いられますが、CakePHP にそれを導入し、一連のファイル操作を行います。

ファイル操作にはリスト取得・アップロード・ダウンロード・削除・コピー・移動が主なものになりますが、今回はそれら全てをコンポーネントで実装していきます。

Contents

  1. 開発環境
  2. AWS SDK for PHP のインストール
  3. 初期設定
    1. IAM資格情報
    2. ローカルストレージ
  4. コンポーネントの作成
    1. コンポーネントの作成
    2. S3Client コンポーネントの実装
  5. コントローラの作成
    1. コントローラの生成
    2. コントローラ実装

開発環境

今回の開発環境は以下の通りです。

  • PHP 7.2
  • composer 1.6.3
  • CakePHP 3.6

CakePHP のルートディレクトリを「cakephp/」とします。

今回は AWS S3 を使用するので、接続可能な IAM ユーザーが必要です。

AWS SDK for PHP のインストール

まずは AWS SDK for PHP をインストールします。バージョンは 3 です。 CakePHP のルートディレクトリに移動し、以下のコマンドを叩きます。

# CakePHP のルートディレクトリへ移動する
cd /path/to/cakephp

# AWS SDK for PHP のインストール
composer require aws/aws-sdk-php

# 実行結果
[demo@localhost cakephp]$ composer require aws/aws-sdk-php
Using version ^3.55 for aws/aws-sdk-php
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 5 installs, 0 updates, 0 removals
  - Installing mtdowling/jmespath.php (2.4.0): Loading from cache
  - Installing guzzlehttp/psr7 (1.4.2): Loading from cache
  - Installing guzzlehttp/promises (v1.3.1): Loading from cache
  - Installing guzzlehttp/guzzle (6.3.3): Downloading (100%)         
  - Installing aws/aws-sdk-php (3.55.3): Downloading (100%)         
aws/aws-sdk-php suggests installing aws/aws-php-sns-message-validator (To validate incoming SNS notifications)
aws/aws-sdk-php suggests installing doctrine/cache (To use the DoctrineCacheAdapter)
Writing lock file
Generating autoload files
> Cake\Composer\Installer\PluginInstaller::postAutoloadDump

初期設定

SDK を使って処理を書くのに必要な設定を初めに行っておきます。

IAM資格情報

S3 に接続可能な IAM ユーザ情報を env ファイルに追記します。

export AWS_S3_BUCKET=your-bucket-name
export AWS_S3_REGION=your-region
export AWS_S3_KEY=YourAccesskeyID
export AWS_S3_SECRET=YourSecretAccesskey

ローカルストレージ

アップロードやダウンロードを行う際のディレクトリを作成します。 CakePHP のルートディレクトリ配下へ storage ディレクトリを作成します。

cakephp
├─ storage

そしてこのディレクトリまでのパスを環境変数として登録します。

cakephp/config/paths.php
define('STORAGE_PATH', ROOT . '/storage');

コンポーネントの作成

aws-sdk-php で操作する為のコンポーネントを作成していきます。

コンポーネントの作成

CakePHP ルートディレクトリへ移動し、以下の Bake コマンドでコンポーネントを生成します。

# CakePHP のルートディレクトリへ移動
cd /path/to/cakephp

# S3Client コンポーネントの生成
bin/cake bake component S3Client

#実行結果
[demo@localhost cakephp]$ bin/cake bake component S3Client

Creating file /path/to/cakephp/src/Controller/Component/S3ClientComponent.php
Wrote `/path/to/cakephp/src/Controller/Component/S3ClientComponent.php`
Deleted `/path/to/cakephp/src/Controller/Component/empty`

Baking test case for App\Controller\Component\S3ClientComponent ...
Deleted `/path/to/cakephp/tests/TestCase/Controller/Component/empty`

Creating file /path/to/cakephp/tests/TestCase/Controller/Component/S3ClientComponentTest.php
Wrote `/path/to/cakephp/tests/TestCase/Controller/Component/S3ClientComponentTest.php`

cakephp/src/Controller/Component 配下に S3ClientComponent.php が生成されます。

cakephp
├─ src
│   ├─ Controller
│   │   ├─ Component
│   │   │   └─ S3ClientComponent.php
cakephp/src/Controller/Component/S3ClientComponent.php
<?php
namespace App\Controller\Component;

use Cake\Controller\Component;
use Cake\Controller\ComponentRegistry;

/**
 * S3Client component
 */
class S3ClientComponent extends Component
{

    /**
     * Default configuration.
     *
     * @var array
     */
    protected $_defaultConfig = [];
}

S3Client コンポーネントの実装

それではコンポーネントを定義します。結果的に、以下のようになりました。

cakephp/src/Controller/Component/S3ClientComponent.php
<?php
namespace App\Controller\Component;

use Cake\Controller\Component;
use Cake\Controller\ComponentRegistry;
use Aws\S3\S3Client;
use Aws\S3\Exception\S3Exception;

/**
 * CakePHP3 S3Client Component
 *            with
 *      AWS SDK for PHP3
 * @see https://aws.amazon.com/jp/sdk-for-php/
 * @see https://github.com/aws/aws-sdk-php
 */
class S3ClientComponent extends Component
{
    protected $_defaultConfig = [];

    protected $default_bucket;

    public function initialize(array $config)
    {
        $this->s3 = S3Client::factory([
            'credentials' => [
                'key' => env('AWS_S3_KEY', ''),
                'secret' => env('AWS_S3_SECRET', ''),
            ],
            'region' => env('AWS_S3_REGION', ''),
            'version' => 'latest',
        ]);

        $this->default_bucket = env('AWS_S3_BUCKET', '');
    }

    /**
     * Get a list of files
     * @param string $bucket_name
     * @param string $dir
     * @param int $get_max
     * @return array
     * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/class-Aws.S3.S3Client.html#_listObjects
     */
    public function getList($bucket_name=null, $dir=null, $get_max=100)
    {
        try {
            if(!$bucket_name) $bucket_name = $this->default_bucket;
            $list_obj = $this->s3->listObjects([
                'Bucket' => $bucket_name,
                'MaxKeys' => $get_max,
                'Prefix' => $dir
            ]);

            foreach ($list_obj['Contents'] as $file) {
                if (mb_substr($file['Key'], -1) !== "/" && (!$dir  || ($dir && strpos($file['Key'], sprintf('%s/', $dir)) !== false))) {
                    $result[] = $file['Key'];
                }
            }

            return $result;
        } catch (S3Exception $e) {
            echo $e->getMessage();
        }
    }

    /**
     * Uploading files
     * @param string $file_path
     * @param string $store_path
     * @param string $bucket_name
     * @return mixed
     * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#putobject
     */
    public function putFile($file_path, $store_path, $bucket_name=null)
    {
        try {
            if(!$bucket_name) $bucket_name = $this->default_bucket;
            $result = $this->s3->putObject(array(
                'Bucket'       => $bucket_name,
                'Key'          => $store_path,
                'SourceFile'   => $file_path,
            ));

            return $result;
        } catch (S3Exception $e) {
            echo $e->getMessage();
        }
    }

    /**
     * File download
     * @param string $s3_file_path
     * @param string $store_dir_path
     * @param string $bucket_name
     * @return mixed
     * @see https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/RetrieveObjSingleOpPHP.html
     */
    public function getFile($s3_file_path, $store_file_path, $bucket_name=null)
    {
        try {
            if(!$bucket_name) $bucket_name = $this->default_bucket;
            $result = $this->s3->getObject([
                'Bucket' => $bucket_name,
                'Key'    => $s3_file_path,
                'SaveAs' => $store_file_path
            ]);

            return $result;
        } catch (S3Exception $e) {
            echo $e->getMessage();
        }
    }

    /**
     * Directory download (Recursive download)
     * @param string $s3_dir_path
     * @param string $local_dir_path
     * @param string $bucket_name
     */
    public function getDirectory($s3_dir_path, $local_dir_path, $bucket_name=null)
    {
        try {
            if(!$bucket_name) $bucket_name = $this->default_bucket;
            $file_list = $this->getList($bucket_name, $s3_dir_path);
            $this->chkDirHandle($file_list, $local_dir_path);
            foreach ($file_list as $from_path) {
                $to_path = sprintf('%s/%s', $local_dir_path, $from_path);
                $this->getFile($from_path, $to_path);
            }
        } catch (S3Exception $e) {
            echo $e->getMessage();
        }
    }

    /**
     * Copying files
     * @param string $s3_file_path
     * @param string $s3_copy_file_path
     * @param string $bucket_name_from
     * @param string $bucket_name_to
     * @return mixed
     * @see https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/CopyingObjectUsingPHP.html
     */
    public function copyFile($s3_file_path, $s3_copy_file_path, $bucket_name_from=null, $bucket_name_to=null)
    {
        try {
            if(!$bucket_name_from) $bucket_name_from = $this->default_bucket;
            if(!$bucket_name_to) $bucket_name_to = $this->default_bucket;
            $result = $this->s3->copyObject(array(
                'Bucket'     => $bucket_name_to,
                'Key'        => $s3_copy_file_path,
                'CopySource' => sprintf('%s/%s', $bucket_name_from, $s3_file_path),
            ));

            return $result;
        } catch (S3Exception $e) {
            echo $e->getMessage();
        }
    }

    /**
     * Copy directory (Recursive copy)
     * @param string $s3_from_dir
     * @param string $s3_to_dir
     * @param string $bucket_name_from
     * @param string $bucket_name_to
     */
    public function copyDirectory($s3_from_dir, $s3_to_dir, $bucket_name_from=null, $bucket_name_to=null)
    {
        try {
            if(!$bucket_name_from) $bucket_name_from = $this->default_bucket;
            if(!$bucket_name_to) $bucket_name_to = $this->default_bucket;
            $file_list = $this->getList($bucket_name_from, $s3_from_dir);

            foreach ($file_list as $from_path) {
                $to_path = sprintf('%s/%s', $s3_to_dir, basename($from_path));
                $this->copyFile($from_path, $to_path);
            }
        } catch (S3Exception $e) {
            echo $e->getMessage();
        }
    }

    /**
     * Moving files
     * @param $s3_from_path
     * @param $s3_to_path
     * @return bool|mixed
     */
    public function moveFile($s3_from_path, $s3_to_path)
    {
        try {
            $result = false;
            if($this->copyFile($s3_from_path, $s3_to_path)) {
                $result = $this->deleteFile($s3_from_path);
            }

            return $result;
        } catch (S3Exception $e) {
            echo $e->getMessage();
        }
    }

    /**
     * Move directory (Recursive movement)
     * @param string $s3_from_dir
     * @param string $s3_to_dir
     * @param string null $bucket_name
     */
    public function moveDirectory($s3_from_dir, $s3_to_dir, $bucket_name=null)
    {
        try {
            if(!$bucket_name) $bucket_name = $this->default_bucket;
            $file_list = $this->getList($bucket_name, $s3_from_dir);
            foreach ($file_list as $from_path) {
                $to_path = sprintf('%s/%s', $s3_to_dir, basename($from_path));
                $this->moveFile($from_path, $to_path);
            }
        } catch (S3Exception $e) {
            echo $e->getMessage();
        }
    }

    /**
     * Delete files
     * @param string $file_path
     * @param string $bucket_name
     * @return mixed
     * @see https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/DeletingMultipleObjectsUsingPHPSDK.html
     */
    public function deleteFile($file_path, $bucket_name=null)
    {
        try {
            if(!$bucket_name) $bucket_name = $this->default_bucket;
            $result = $this->s3->deleteObject(array(
                'Bucket' => $bucket_name,
                'Key'    => $file_path
            ));

            return $result;
        } catch (S3Exception $e) {
            echo $e->getMessage();
        }
    }

    /**
     * Delete directory (Remove recursively)
     * @param string $dir_name
     * @param string $bucket_name
     * @return mixed
     * @see https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/DeletingMultipleObjectsUsingPHPSDK.html
     * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#deleteobjects
     */
    public function deleteDirectory($dir_name, $bucket_name=null)
    {
        try {
            if(!$bucket_name) $bucket_name = $this->default_bucket;
            $file_list = $this->getList($bucket_name, $dir_name);
            $files = $this->createArrayMultipleObjects($file_list);

            $result = $this->s3->deleteObjects(array(
                'Bucket'  => $bucket_name,
                'Delete' => [
                    'Objects' => $files
                ]
            ));

            return $result;
        } catch (S3Exception $e) {
            echo $e->getMessage();
        }
    }

    /**
     * Convert from file list to array for multiple objects
     * @param $file_list
     * @return array
     */
    private function createArrayMultipleObjects($file_list)
    {
        foreach ($file_list as $name) {
            $files[] = array('Key' => $name);
        }
        return $files;
    }

    /**
     * Recursively check the path directories in the file list
     * @param $file_list
     */
    private function chkDirHandle($file_list, $local_dir_path)
    {
        foreach ($file_list as $filename) {
            $local_path = sprintf('%s/%s', $local_dir_path, dirname($filename));
            $this->chkDir($local_path);
        }
    }
    /**
     * Confirm existence of directory and create it if it does not exist.
     * @param $local_dir_path
     */
    private function chkDir($local_dir_path)
    {
        if(!file_exists($local_dir_path)) {
            mkdir($local_dir_path, 0777, true);
        }
    }
}

上から解説します。

initialize()

public function initialize(array $config)
{
    $this->s3 = S3Client::factory([
        'credentials' => [
            'key' => env('AWS_S3_KEY', ''),
            'secret' => env('AWS_S3_SECRET', ''),
        ],
        'region' => env('AWS_S3_REGION', ''),
        'version' => 'latest',
    ]);

    $this->default_bucket = env('AWS_S3_BUCKET', '');
}

コンストラクタで S3Client の設定を行っています。そして、バケット名だけはメンバ変数 $default_bucket に格納し、操作する際に自由にバケットを変更できるようにしています。各メソッドの引数にバケット名を渡さない場合は、このデフォルトのバケット名が使用されます。

getList()

public function getList($bucket_name=null, $dir=null, $get_max=100)
{
    try {
        if(!$bucket_name) $bucket_name = $this->default_bucket;
        $list_obj = $this->s3->listObjects([
            'Bucket' => $bucket_name,
            'MaxKeys' => $get_max,
            'Prefix' => $dir
        ]);

        foreach ($list_obj['Contents'] as $file) {
            if (mb_substr($file['Key'], -1) !== "/" && (!$dir  || ($dir && strpos($file['Key'], sprintf('%s/', $dir)) !== false))) {
                $result[] = $file['Key'];
            }
        }

        return $result;
    } catch (S3Exception $e) {
        echo $e->getMessage();
    }
}

getList() メソッドでは、ファイルの一覧を取得します。引数にはバケット名、ディレクトリ、取得上限数を取ります。バケット名は渡さなければデフォルトのバケット名が使われます。取得上限数の上限設定値は 1000 です。

putFile()

public function putFile($file_path, $store_path, $bucket_name=null)
{
    try {
        if(!$bucket_name) $bucket_name = $this->default_bucket;
        $result = $this->s3->putObject(array(
            'Bucket'       => $bucket_name,
            'Key'          => $store_path,
            'SourceFile'   => $file_path,
        ));

        return $result;
    } catch (S3Exception $e) {
        echo $e->getMessage();
    }
}

putFile() メソッドでは、1 つのファイルのアップロード処理を行います。引数にはアップロード元ファイルパス、アップロード先ファイルパス、バケット名を取ります。

getFile()

public function getFile($s3_file_path, $store_dir_path, $bucket_name=null)
{
    try {
        if(!$bucket_name) $bucket_name = $this->default_bucket;
        $result = $this->s3->getObject([
            'Bucket' => $bucket_name,
            'Key'    => $s3_file_path,
            'SaveAs' => $store_dir_path
        ]);

        return $result;
    } catch (S3Exception $e) {
        echo $e->getMessage();
    }
}

getFile() メソッドでは、ファイルのダウンロード処理を行います。引数には S3 上のファイルパス、保存するローカルのファイルパス、バケット名を取ります。

getDirectory()

public function getDirectory($s3_dir_path, $local_dir_path, $bucket_name=null)
{
    try {
        if(!$bucket_name) $bucket_name = $this->default_bucket;
        $file_list = $this->getList($bucket_name, $s3_dir_path);
        $this->chkDirHandle($file_list, $local_dir_path);
        foreach ($file_list as $from_path) {
            $to_path = sprintf('%s/%s', $local_dir_path, $from_path);
            $this->getFile($from_path, $to_path);
        }
    } catch (S3Exception $e) {
        echo $e->getMessage();
    }
}

getDirectory() メソッドでは、指定したディレクトリをダウンロードします。指定ディレクトリ以下を再帰的(ディレクトリ構造を保ったまま)にダウンロードします。引数には、ダウンロードする S3 のディレクトリ、保存するローカルのディレクトリパス、バケット名を取ります。

copyFile()

public function copyFile($s3_file_path, $s3_copy_file_path, $bucket_name_from=null, $bucket_name_to=null)
{
    try {
        if(!$bucket_name_from) $bucket_name_from = $this->default_bucket;
        if(!$bucket_name_to) $bucket_name_to = $this->default_bucket;
        $result = $this->s3->copyObject(array(
            'Bucket'     => $bucket_name_to,
            'Key'        => $s3_copy_file_path,
            'CopySource' => sprintf('%s/%s', $bucket_name_from, $s3_file_path),
        ));

        return $result;
    } catch (S3Exception $e) {
        echo $e->getMessage();
    }
}

copyFile() メソッドでは、ファイルを S3 内で 1 つのファイルをコピーします。引数にはコピー元ファイルパス、コピー先ファイルパス、コピー元バケット名、コピー先バケット名を取ります。

copyDirectory()

public function copyDirectory($s3_from_dir, $s3_to_dir, $bucket_name_from=null, $bucket_name_to=null)
{
    try {
        if(!$bucket_name_from) $bucket_name_from = $this->default_bucket;
        if(!$bucket_name_to) $bucket_name_to = $this->default_bucket;
        $file_list = $this->getList($bucket_name_from, $s3_from_dir);

        foreach ($file_list as $from_path) {
            $to_path = sprintf('%s/%s', $s3_to_dir, basename($from_path));
            $this->copyFile($from_path, $to_path);
        }
    } catch (S3Exception $e) {
        echo $e->getMessage();
    }
}

copyDirectory() メソッドでは、S3 内でディレクトリをコピー処理します。ファイルは再帰的(ディレクトリ構成を保ったまま)にコピーされます。引数にはコピー元 S3 ファイルパス、コピー先 S3 ファイルパス、コピー元バケット名、コピー先バケット名を取ります。

moveFile()

public function moveFile($s3_from_path, $s3_to_path)
{
    try {
        $result = false;
        if($this->copyFile($s3_from_path, $s3_to_path)) {
            $result = $this->deleteFile($s3_from_path);
        }

        return $result;
    } catch (S3Exception $e) {
        echo $e->getMessage();
    }
}

moveFile() メソッドでは、S3 内で 1 つのファイルを移動します。引数には移動基ファイルパス、移動先ファイルパスを取ります。

moveDirectory()

public function moveDirectory($s3_from_dir, $s3_to_dir, $bucket_name=null)
{
    try {
        if(!$bucket_name) $bucket_name = $this->default_bucket;
        $file_list = $this->getList($bucket_name, $s3_from_dir);
        foreach ($file_list as $from_path) {
            $to_path = sprintf('%s/%s', $s3_to_dir, basename($from_path));
            $this->moveFile($from_path, $to_path);
        }
    } catch (S3Exception $e) {
        echo $e->getMessage();
    }
}

moveDirectory() メソッドでは、S3 内でディレクトリを移動します。ファイルは再帰的(ディレクトリ構成を保ったまま)移動します。引数には移動元ディレクトリパス、移動先ディレクトリパス、バケット名を取ります。

deleteFile()

public function deleteFile($file_path, $bucket_name=null)
{
    try {
        if(!$bucket_name) $bucket_name = $this->default_bucket;
        $result = $this->s3->deleteObject(array(
            'Bucket' => $bucket_name,
            'Key'    => $file_path
        ));

        return $result;
    } catch (S3Exception $e) {
        echo $e->getMessage();
    }
}

deleteFile() メソッドでは、1 つのファイルを削除します。引数には削除する S3 内のファイルパス、バケット名を取ります。

deleteDirectory()

public function deleteDirectory($dir_name, $bucket_name=null)
{
    try {
        if(!$bucket_name) $bucket_name = $this->default_bucket;
        $file_list = $this->getList($bucket_name, $dir_name);
        $files = $this->createArrayMultipleObjects($file_list);

        $result = $this->s3->deleteObjects(array(
            'Bucket'  => $bucket_name,
            'Delete' => [
                'Objects' => $files
            ]
        ));

        return $result;
    } catch (S3Exception $e) {
        echo $e->getMessage();
    }
}

deleteDirectory() では、S3 内のディレクトリを削除します。対象ディレクトリ内のファイルは全て削除されます。引数には削除対象ディレクトリパス、バケット名を取ります。

これより以下は、上記メソッドをサポートするメソッド群です。

createArrayMultipleObjects()

private function createArrayMultipleObjects($file_list)
{
    foreach ($file_list as $name) {
        $files[] = array('Key' => $name);
    }
    return $files;
}

createArrayMultipleObjects() メソッドでは、複数オブジェクトを削除する為のデータ構成を作成します。引数には getList() メソッドで取得したファイルリストを取ります。

chkDirHandle()

private function chkDirHandle($file_list, $local_dir_path)
{
    foreach ($file_list as $filename) {
        $local_path = sprintf('%s/%s', $local_dir_path, dirname($filename));
        $this->chkDir($local_path);
    }
}

chkDirHandle() メソッドは、ディレクトリ群を再帰的に処理する為のハンドラです。ファイルパスを適切な形へ整形し、chkDir() メソッドに渡します。

chkDir()

private function chkDir($local_dir_path)
{
    if(!file_exists($local_dir_path)) {
        mkdir($local_dir_path, 0777, true);
    }
}

chkDir() メソッドでは、ローカルでの指定ディレクトリの存在確認を行い、存在しない場合はそのディレクトリを作成します。

コントローラの作成

基本的にはコンポーネントを用いれば一通りの操作が行えますが、動作例として、コントローラを作成します。

コントローラの生成

コントローラファイルを生成します。 CakePHP ルートディレクトリへ移動し、以下の Bake コマンドを叩きます。

# CakePHP のルートディレクトリへ移動
cd /path/to/cakephp

# S3 コントローラの生成
bin/cake bake controller S3

#実行結果
[demo@localhost cakephp]$ bin/cake bake controller S3

Baking controller class for S3...

Creating file /path/to/cakephp/src/Controller/S3Controller.php
Wrote `/path/to/cakephp/src/Controller/S3Controller.php`
Bake is detecting possible fixtures...

Baking test case for App\Controller\S3Controller ...

Creating file /path/to/cakephp/tests/TestCase/Controller/S3ControllerTest.php
Wrote `/path/to/cakephp/tests/TestCase/Controller/S3ControllerTest.php`

cakephp/src/Controller 配下に S3Controller.php が生成されます。

cakephp
├─ src
│   ├─ Controller
│   │   ├─ S3Controller.php

コントローラ実装

コントローラを実装します。以下のようになります。

cakephp/src/Controller/S3Controller.php
<?php
namespace App\Controller;

use App\Controller\AppController;

class S3Controller extends AppController
{
    protected $storage_path;
    
    public function initialize()
    {
        parent::initialize();
        $this->loadComponent('S3Client');
        $this->autoRender = false;

        $this->storage_path = STORAGE_PATH;
    }

    public function getList()
    {
        $file_list = $this->S3Client->getList(null);
        print_r($file_list); exit;
    }

    public function upload()
    {
        $file_name = "test.txt";
        $store_dir = "ddd/";

        $file_local_path = sprintf('%s/%s', $this->storage_path, $file_name);
        $file_store_path = sprintf('%s%s', $store_dir, $file_name);

        $result = $this->S3Client->putFile($file_local_path, $file_store_path);
    }

    public function download()
    {
        $file_name = "test.png";
        $s3_dir = "";
        $store_dir = sprintf('%s/d', $this->storage_path);

        $s3_file_path = sprintf('%s%s', $s3_dir, $file_name);
        $store_file_path = sprintf('%s/%s', $store_dir, $file_name);

        $file_obj = $this->S3Client->getFile($s3_file_path, $store_file_path);
    }

    public function downloadDirectory()
    {
        $s3_dir = "cp";
        $local_dir = "dl";
        $local_dir_path = sprintf('%s/%s', $this->storage_path, $local_dir);
        $this->S3Client->getDirectory($s3_dir, $local_dir_path);
    }

    public function copy()
    {
        $file_name = "test.png";
        $s3_dir = "";
        $s3_copy_dir = "cp/";

        $s3_file_path = sprintf('%s%s', $s3_dir, $file_name);
        $s3_copy_file_path = sprintf('%s%s', $s3_copy_dir, $file_name);

        $this->S3Client->copyFile($s3_file_path, $s3_copy_file_path);
    }

    public function copyDirectory()
    {
        $s3_from_dir = "cp";
        $s3_to_dir = "cp_d";
        $this->S3Client->copyDirectory($s3_from_dir, $s3_to_dir);
    }

    public function move()
    {
        $file_name = "test.png";
        $s3_from_dir = "cp/";
        $s3_to_dir = "mv/";
        $s3_from_path = sprintf('%s%s', $s3_from_dir, $file_name);
        $s3_to_path = sprintf('%s%s', $s3_to_dir, $file_name);
        $this->S3Client->moveFile($s3_from_path, $s3_to_path);
    }

    public function moveDirectory()
    {
        $s3_from_dir = "mv";
        $s3_to_dir = "mv_d";
        $this->S3Client->moveDirectory($s3_from_dir, $s3_to_dir);
    }

    public function delete()
    {
        $s3_file_path = 'cp/test.png';
        $this->S3Client->deleteFile($s3_file_path);
    }

    public function deleteDirectory()
    {
        $s3_dir_path = 'cp';
        $this->S3Client->deleteDirectory($s3_dir_path);
    }
}

アクション(メソッド)名からその内容はわかると思いますが、

$this->loadComponent('S3Client');

上記にて S3Client コンポーネントを読み込み、実行しています。アクション内では、適宜対象のファイルやパスを指定している流れになっています。

まとめ

以上で作業は完了になります。 AWS CLI を使って操作するのも良いですが、AWS SDK for PHP を導入する事で、インフラ側の用意が不要になるので、構築の際の作業範囲にインフラ側が無い場合はこちら側の作業で導入できて便利なので是非試してみてください。

ちなみに今回作ったコンポーネントは、確認用コントローラも含め、Github に上げてあります。

CakePHP と AWS SDK for PHP3 を使った S3 ファイル操作コンポーネント
https://github.com/rito-nishino/cakephp-s3-aws-sdk-for-php

AWS SDK for PHP
https://aws.amazon.com/jp/sdk-for-php/

Author

rito

  • Backend Engineer
  • Tokyo, Japan
  • PHP 5 技術者認定上級試験 認定者
  • 統計検定 3 級