aws-sdk-phpで5GB以上のファイルをS3にアップロードする方法

## 何の話？
**S3に5GB以上のファイルを、aws-sdk-phpのS3のputObjectを使ってアップロードしようとしたら、以下のエラーが出た。**

1ファイルあたりのアップロードできる上限サイズは、`5368709120byte(5.36870912GB)`なのに、
`5506553726byte(5.506553726GB)`アップロードしようとしてると怒られている。

```
Error executing "PutObject" on "https://xxxx.s3.ap-northeast-1.amazonaws.com/path/filename"; 
AWS HTTP error: Client error: `PUT https://xxxx.s3.ap-northeast-1.amazonaws.com/path/filename` resulted in a `400 Bad Request` 
```

```xml
<?xml version='1.0' encoding='utf-8'?>
<error>
    <code>
        EntityTooLarge
    </code>
    <message>
        Your proposed upload exceeds the maxim (truncated...)
    EntityTooLarge (client): Your proposed upload exceeds the maximum allowed size -
        <?xml version='1.0' encoding='utf-8'?>
    </message>
</error>
<error>
    <code>
        EntityTooLarge
    </code>
    <message>
        Your proposed upload exceeds the maximum allowed size
    </message>
    <proposedsize>
        5506553726
    </proposedsize>
    <maxsizeallowed>
        5368709120
    </maxsizeallowed>
    <requestid>
        DCB569101CF240C0
    </requestid>
    <hostid>
        xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    </hostid>
</error>
```


## AWSのよくある質問を見ると

> Q: どれほどの量のデータを保存できますか?
> 
> 格納可能なデータの総量とオブジェクトの数には制限はありません。個別の Amazon S3 オブジェクトのサイズは、最低 0 バイトから最大 5  テラバイトまでさまざまです。1つの PUT にアップロード可能なオブジェクトの最大サイズは 5 GB です。100 MB 以上のオブジェクトの場合は、Multipart Upload 機能を使うことをお考えください。

https://aws.amazon.com/jp/s3/faqs/

総量とオブジェクトの数には制限はないが、1つの PUT にアップロード可能なオブジェクトの最大サイズは 5 GBらしい。
100 MB 以上のオブジェクトの場合は、[Multipart Upload](https://docs.aws.amazon.com/AmazonS3/latest/dev/UploadingObjects.html) 機能を使うことをお考えください、とある。

## MultipartUploaderとは
以下のサイトに`MultipartUploader`を使って、5GB以上のファイルでもアップロードする方法が書いてある。
最大5TBのファイルまでアップロードできるらしい。
Amazon S3 オブジェクトのサイズの上限までってことか。

> With a single PutObject operation, you can upload objects up to 5 GB in size. However, by using the multipart uploads (e.g., CreateMultipartUpload, UploadPart, CompleteMultipartUpload, AbortMultipartUpload), you can upload object up to 5 TB in size.

[Amazon S3 Multipart Uploads](https://docs.aws.amazon.com/aws-sdk-php/v3/guide/service/s3-multipart-upload.html)

## MultipartUploaderを使ってみる
### composer
aws-sdk-phpがインストールされていることが前提。
composer以外の方法でインストールしてもOK。

```json:composer.json
{
    "autoload": {
        "psr-4": {
        }
    },
    "require": {
        "aws/aws-sdk-php": "3.*"
    }
}
```

## PHPのソースを作成
以下のソースで、5GB以上のファイルもアップロードできた。

```php
<?php

require(dirname(__FILE__) . '/vendor/autoload.php');

use Aws\S3\S3Client;
use Aws\S3\MultipartUploader;
use Aws\Exception\MultipartUploadException;

$s3Client = S3Client::factory([
    'version' => '2006-03-01',
    'key' => 'xxxxxxxx',
    'secret' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
    'region' => 'ap-northeast-1'
]);


$bucketname = 'sample-bucket';
$from_path = './bigdata.csv';
$to_path = 'dirname/bigdata.csv';

$uploader = new MultipartUploader($s3Client, $from_path, [
    'bucket' => $bucketname,
    'key'    => $to_path,
]);

try {
    $result = $uploader->upload();
    print_r($result);
    echo $result['ObjectURL'];
} catch (MultipartUploadException $e) {
    echo $e->getMessage();
}
```

以上