RitoLabo

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

  • 公開:
  • カテゴリ: PHP CakePHP
  • タグ: PHP,AWS,S3,CakePHP,3.5,Component,3.6,SDK

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

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

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

開発環境

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

  • Linux CentOS 7
  • Apache 2.4
  • PHP 7.2/7.1
  • composer 1.6.3
  • CakePHP 3.6/3.5

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=ap-northeast-1
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/