S3の基本的な操作をしたメモ(AWS SDK for PHP 3.x)

##やってみた感想

* [Goofys](https://github.com/kahing/goofys)で S3 を mountした方が楽な気がする。

* [S3Client](http://docs.aws.amazon.com/aws-sdk-php/v3/api/class-Aws.S3.S3Client.html) で[AWS Signature Version 4](https://docs.aws.amazon.com/ja_jp/general/latest/gr/signature-version-4.html)する方法が解らなかった。
 
##環境 EC2 + S3
* EC2 
t2.nano (region=us-west-2a)
Amazon Linux AMI release 2016.03
PHP 7.0.7 (cli) (built: May 25 2016 18:36:46) ( NTS )
Server version: Apache/2.2.31 (Unix)

* S3 (region=us-west-2)

##S3の構築

###[バケットの作成](http://docs.aws.amazon.com/ja_jp/AmazonS3/latest/gsg/CreatingABucket.html)

任意のバケット名を入力してクリッククリック。

###S3アクセス用IAMユーザ作成

* [AWS アカウント内での IAM ユーザーの作成]
(http://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_users_create.html)

credentials.csv をダウンロードしておく。
中身はこんな感じ

```csv:credentials.csv
User Name,Access Key Id,Secret Access Key
"IAMのユーザ名",アクセスキーID文字列,アクセスキー文字列
```

###作成したIAMユーザにポリシー設定
 
[IAM ポリシーの概要](http://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/access_policies.html)

```json:iam-user-policies
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:DeleteObject",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::作成したバケット名",
                "arn:aws:s3:::作成したバケット名/*"
            ]
        }
    ]
}
```

## credentials.ini 作成

* [Credentials](http://docs.aws.amazon.com/aws-sdk-php/v3/guide/guide/credentials.html)

credentials.csvを元に適切な場所に作る。

```ini:credentials.ini
[任意のセクション名]
aws_access_key_id = アクセスキーID文字列
aws_secret_access_key = アクセスキー文字列
```

##AWS SDK for PHP v3の取得

今回はzipを落としてきてやってみました。

* [Installing via Zip](http://docs.aws.amazon.com/aws-sdk-php/v3/guide/getting-started/installation.html)
 * [download the zip file](http://docs.aws.amazon.com/aws-sdk-php/v3/download/aws.zip)

```command:wget
$ sudo wget http://docs.aws.amazon.com/aws-sdk-php/v3/download/aws.zip
```
これを解凍して使います。

##a.jpgをPUT,GET,DELETEしてみる。

* 使うもの
 * [S3Client](http://docs.aws.amazon.com/aws-sdk-php/v3/api/class-Aws.S3.S3Client.html) 

* この例はtry-catchとか省略してます。
 * 参照 [Aws\S3\Exception](http://docs.aws.amazon.com/aws-sdk-php/v3/api/class-Aws.S3.Exception.S3Exception.html)

* key にセットする任意の文字列で識別
 * key に 'subdir\filename' と指定するとsubdirがバケット内に自動で作られる。

* 当然ですが、GET時にsaveAsの /path/toに書き込み権限が必要。

```php:sample1.php
<?php
require '/path/to/aws/aws-autoloader.php';

use Aws\Credentials\CredentialProvider;
$ini = '/path/to/credentials.ini';
$iniProvider = CredentialProvider::ini('任意のセクション名', $ini);
$iniProvider = CredentialProvider::memoize($iniProvider);

$client = new Aws\S3\S3Client([
    'region'   => 'us-west-2',
    'version'  => '2006-03-01',
    'credentials' => $iniProvider
]);

//a.jpgをバケットに入れる。
$bucketName = '作成したバケット名';
$keyName = 'a.jpg';
$srcFile = '/path/to/a.jpg';

$client->putObject([
    'Bucket' => $bucketName,
    'Key' => $keyName,
    'SourceFile' => $srcFile,
    'ContentType'=> mime_content_type($srcFile)
]);

//バケットからa.jpgを取り出して、save.jpgとして保存
$saveFile = '/path/to/save.jpg';

$client->getObject([
    'Bucket' => $bucketName,
    'Key' => $keyName,
    'SaveAs' => $saveFile
]);

//バケット内のa.jpgを削除
$client->deleteObject([
    'Bucket' => $bucketName,
    'Key' => $keyName
]);

```

##dir単位で出し入れ

* 使うもの
 * [Amazon S3 Transfer Manager](http://docs.aws.amazon.com/aws-sdk-php/v3/guide/service/s3-transfer.html)

* php-xml が必要です。
 * installされてないと 'SimpleXMLElement' not found　となる。

* バケットにsubdir指定可能

```php:sample2.php
<?php
require '/path/to/aws-autoloader.php';

use Aws\Credentials\CredentialProvider;
$ini = '/path/to/credentials.ini';
$iniProvider = CredentialProvider::ini('任意のセクション名', $ini);
$iniProvider = CredentialProvider::memoize($iniProvider);

$client = new Aws\S3\S3Client([
    'region'    => 'us-west-2',
    'version'   => '2006-03-01',
    'credentials' => $iniProvider
]);

$bucketName = 's3://作成したバケット名';
//$bucketName = 's3://作成したバケット名/subdir';

$s3Transfer = new \Aws\S3\Transfer($client, '/path/to/uploadDir', $bucketName);
$s3Transfer->transfer(); //upload

$s3Transfer = new \Aws\S3\Transfer($client, $bucketName, '/path/to/downloadDir');
$s3Transfer->transfer(); //download

```

sampleにコピペミスあったらすみません。
一応動いた物を元にしたメモです。