CloudNのObjectStorageをAWS SDK for PHP 2.xで操作する


## はじめに

[CloudN](http://www.ntt.com/cloudn/)の[Object Storage](http://www.ntt.com/cloudn/data/storage.html)は、Amazon S3 互換なので、[AWS SDK for PHP](http://aws.amazon.com/jp/sdk-for-php/)を利用できるわけですが、バージョン 3は使えないので注意が必要です。

## AWS互換機能についての制限

なかなかこの情報にたどりつかないのですが、CloudNの[このページ](http://www.cloudn-service.com/guide/manuals/html/objectstorage/rsts/Introduction/service_spec.html#aws
)に本当にサラッと記載があります。

```
- 以下の機能はサポートしておりません
  - ロギング（Logging）
  - Signature Version 4による署名
```

この`Signature Version 4`（`署名バージョン4`）がサポートされないとなると、`署名バージョン 2`を使いたいわけですが、AWS SDK for PHP 3.xで、`署名バージョン 2`は使えない(後述)のと、対象プロジェクトが、`"guzzle/guzzle": "~3.7"`だったので、結果、AWS SDK for PHP 2.xを使うことにしました。

### AWS SDK for PHP 3.x における署名バージョンの扱い

2015年5月に、`署名バージョン 2`はAWS SDK for PHPから削除されました。

Removing services that do not support Signature Version 4.
https://github.com/aws/aws-sdk-php/pull/575

Removing S3's old Signature; use Signature Version 4 exclusively
https://github.com/aws/aws-sdk-php/pull/581

現在（2015/6/21）は、`署名バージョン 4`と匿名認証（anonymous）のみサポートしているようです。

```php
// https://github.com/aws/aws-sdk-php/blob/master/src/Signature/SignatureProvider.php
/**
 * Creates signature objects from known signature versions.
 *
 * This provider currently recognizes the following signature versions:
 *
 * - v4: Signature version 4.
 * - anonymous: Does not sign requests.
 *
 * @return callable
 */
public static function version()
{
    return function ($version, $service, $region) {
        switch ($version) {
            case 'v4':
                return $service === 's3'
                    ? new S3SignatureV4($service, $region)
                    : new SignatureV4($service, $region);
            case 'anonymous':
                return new AnonymousSignature();
            default:
                return null;
        }
    };
}
```

下記のドキュメント見る限りは、`署名バージョン 2`も使えるように見えるので、AWS SDK for PHP 3.x では`署名バージョン 4`のみサポートすることを明示してほしいです。
（CloudNが`署名バージョン 4`をサポートするのが筋なのかもしれませんが）

https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/UsingAWSSDK.html

```
リクエスト認証での署名バージョンの指定

Amazon S3 は、中国（北京）および 欧州 (フランクフルト) リージョンでは署名バージョン 4 のみをサポートしており、AWS SDK はこの署名バージョンを使用してリクエストを認証します。

他のすべてのリージョンでは、Amazon S3 は署名バージョン 4 と署名バージョン 2 の両方をサポートします。これらのリージョンでは、AWS SDK はデフォルトで署名バージョン 2 を使用してリクエストを認証します。オプションで、以下の表に示すように、署名バージョン 4 を使うよう SDK にリクエストすることができます。
```


## インストール

前置きが長くなりましたが、SilexのプロジェクトにAWS SDK for PHPを導入していきます。

### aws/aws-sdk-php-silex 1.1.0

詳細は、[こちら](https://packagist.org/packages/aws/aws-sdk-php-silex#1.1.0)を確認ください。
`aws-sdk-php-silex` 2.0以降は、`AWS SDK for PHP`が3.xになってしまうので、必ず1.xをインストールするようにします。

```bash
$ composer require "aws/aws-sdk-php-silex": "~1.1" 
```

### AwsServiceProvider を登録

[README](https://github.com/aws/aws-sdk-php-silex/blob/master/README.md)にしたがって、AwsServiceProviderに登録します。

```php
$app->register(new \Aws\Silex\AwsServiceProvider(), [
	'aws.config' => [
        'version' => 'latest',
        'endpoint' => 'https://str.cloudn-service.com',
        'credentials' => [
            'key' => 'your access key',
            'secret' => 'your secret key'
        ],
        'region' => 'jp-east1'
	]
]);
```

あとは、下記のように、$app['aws']から、`Aws\Common\Aws`を取り出して、`Aws\S3\S3Client`をgetすれば、準備完了です。

```php
use Aws\Common\Aws;
use Aws\S3\S3Client;

$aws = $app['aws'];
/* @var $aws Aws */
$s3 = $aws->get('s3');
/* @var $s3 S3Client */
```

## Objcetc Storageの操作

### ダウンロード

```php
$s3->getObject([
    'Bucket' => 'bucket name',
    'Key' => 'path/to/object'
]);
```

### アップロード

```php
$s3->upload('bucket name', 'path/to/object', $data);
```

### 削除

```php
$s3->deleteObject([
    'Bucket' => 'bucket name',
    'Key' => '/path/to/object'
]);
```

## まとめ
Object Storageの操作方法でというよりは、導入するまでの道のりに地雷がありました。
何も考えずに、AWS SDK for PHP 3.xを`composer require`してしまった人は高確立で踏む地雷かと思いますので、参考にしていただければと思います。