

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 使用第 3 版在 Amazon S3 之間傳輸目錄 適用於 PHP 的 AWS SDK
<a name="s3-transfer"></a>

您可以使用第 3 適用於 PHP 的 AWS SDK 版中的 `Transfer`類別，將整個目錄上傳至 Amazon S3 儲存貯體，並將整個儲存貯體下載至本機目錄。

## 將本機目錄上傳至 Amazon S3
<a name="uploading-a-local-directory-to-s3"></a>

[https://docs.aws.amazon.com/aws-sdk-php/v3/api/class-Aws.S3.Transfer.html](https://docs.aws.amazon.com/aws-sdk-php/v3/api/class-Aws.S3.Transfer.html) 物件會執行傳輸。下列範例示範如何以遞迴方式將檔案的本機目錄上傳至 Amazon S3 儲存貯體。

```
// Create an S3 client.
$client = new \Aws\S3\S3Client([
    'region'  => 'us-west-2',
    'version' => '2006-03-01',
]);

// Where the files will be sourced from.
$source = '/path/to/source/files';

// Where the files will be transferred to.
$dest = 's3://bucket';

// Create a transfer object.
$directoryTransfer = new \Aws\S3\Transfer($client, $source, $dest);

// Perform the transfer synchronously.
$directoryTransfer->transfer();
```

在此範例中，我們建立 Amazon S3 用戶端、建立 `Transfer` 物件，並同步執行傳輸。

上一個範例示範執行傳輸所需的最低程式碼量。`Transfer` 物件也可以以非同步方式執行傳輸，並具有可用於自訂傳輸的各種組態選項。

您可以在 `s3://` URI 中提供金鑰字首，將本機檔案上傳至 Amazon S3 儲存貯體的「子資料夾」。下列的範例將磁碟上的本機檔案上傳到 `bucket` 儲存貯體，並儲存金鑰前綴為 `foo` 的儲存檔案。

```
$source = '/path/to/source/files';
$dest = 's3://bucket/foo';
$directoryTransfer = new \Aws\S3\Transfer($client, $source, $dest);
$directoryTransfer->transfer();
```

## 下載 Amazon S3 儲存貯體
<a name="downloading-an-s3-bucket"></a>

您可以將`$source`引數指定為 Amazon S3 URI （例如 `s3://bucket`)，並將`$dest`引數指定為本機目錄的路徑，以遞迴方式將 Amazon S3 儲存貯體下載至磁碟上的本機目錄。

```
// Where the files will be sourced from.
$source = 's3://bucket';

// Where the files will be transferred to.
$dest = '/path/to/destination/dir';

$directoryTransfer = new \Aws\S3\Transfer($client, $source, $dest);
$directoryTransfer->transfer();
```

**注意**  
開發套件會在下載儲存貯體中的物件時自動建立任何必要的目錄。

您可以在儲存貯體之後的 Amazon S3 URI 中包含金鑰字首，以僅下載存放在「虛擬資料夾」下的物件。以下範例只會下載指定儲存貯體以 ”/foo” 金鑰前綴儲存的檔案。

```
$source = 's3://bucket/foo';
$dest = '/path/to/destination/dir';
$directoryTransfer = new \Aws\S3\Transfer($client, $source, $dest);
$directoryTransfer->transfer();
```

## Configuration
<a name="configuration"></a>

`Transfer` 物件建構函式接受下列引數。

** `$client` **  
用來執行傳輸的 `Aws\ClientInterface` 物件。

** `$source` （字串 \$1 `Iterator`)**  
正在傳輸的原始碼資料。這可以指向磁碟上的本機路徑 （例如 `/path/to/files`) 或 Amazon S3 儲存貯體 （例如 `s3://bucket`)。`s3://` URI 也可以包含金鑰前綴，用來只傳輸使用共同前綴的物件。  
如果`$source`引數是 Amazon S3 URI，則`$dest`引數必須是本機目錄 （反之亦然）。  
除了提供字串值，您也可以提供 `\Iterator` 物件，此物件會產生絕對的檔案名稱。如果您提供 `\Iterator` 物件，**則必須**在`$options`關聯陣列中提供`base_dir`選項。

** `$dest` **  
檔案傳輸的目的地。如果`$source`引數是磁碟上的本機路徑， `$dest` 必須是 Amazon S3 儲存貯體 URI （例如 `s3://bucket`)。如果`$source`引數是 Amazon S3 儲存貯體 URI，則`$dest`引數必須是磁碟上的本機路徑。

** `$options` **  
傳輸選項的關聯陣列。下列傳輸選項有效：    
**`add_content_md5` (bool)**  
設定為 `true`以計算上傳的 MD5 檢查總和。  
** `base_dir` (string)**  
來源的基本目錄 (如果 `$source` 為疊代器)。如果 `$source` 選項不是陣列，則會略過此選項。  
** `before` (可呼叫)**  
在每次傳輸前呼叫的回呼函式。回呼函式應具有像是 `function (Aws\Command $command) {...}` 的函式簽章。提供的命令將會是 `GetObject`、`PutObject`、`CreateMultipartUpload`、`UploadPart` 或 `CompleteMultipartUpload` 命令。  
** `mup_threshold` (int)**  
分段上傳應使用的大小 (而非使用 `PutObject`)，單位為位元組。預設為 `16777216` (16 MB)。  
** `concurrency` (整數，預設 = 5)**  
要同時上傳的檔案數量。理想的並行值，將會視待上傳檔案的數量，以及每個檔案的平均大小而有不同。一般而言，相較於大型檔案，較小的檔案在並行數值較高時具有較大的優勢。  
** `debug` (bool)**  
設定為 `true` 可印出傳輸的偵錯資訊。設定為 `fopen()` 資源，可寫入特定串流，而非寫入 STDOUT。

## 非同步傳輸
<a name="async-transfers"></a>

`Transfer` 物件是 `GuzzleHttp\Promise\PromisorInterface` 的執行個體。這表示傳輸可以非同步進行，也可透過呼叫物件的 `promise` 方法來起始。

```
$source = '/path/to/source/files';
$dest = 's3://bucket';
$directoryTransfer = new \Aws\S3\Transfer($client, $source, $dest);

// Initiate the transfer and get a promise.
$promise = $directoryTransfer->promise();

// Do something when the transfer is complete using the then() method.
$promise->then(function () {
    echo 'Done!';
});
```

如果任何檔案無法傳輸，承諾會遭到拒絕。您可以使用 promise 物件的 `otherwise` 方法，來以非同步方式處理失敗的傳輸。`otherwise` 函式可接受回呼，在發生錯誤時呼叫。回呼接受 `$reason` 的拒絕，這通常是 的執行個體 `Aws\Exception\AwsException`（雖然**任何類型的**值都可以傳遞給回呼）。

```
$promise->otherwise(function ($reason) {
    echo 'Transfer failed: ';
    var_dump($reason);
});
```

由於 `Transfer` 物件會傳回 promise 的值，這些傳輸可和其他的非同步 promise 物件同時執行。

## 自訂目錄傳輸
<a name="customizing-the-transfer-manager-s-commands"></a>

透過將回呼新增至建構函數，您可以自訂 `Transfer`執行的選項。

```
$uploader = new Transfer($s3Client, $source, $dest, [
    'before' => function (\Aws\Command $command) {
        // Commands can vary for multipart uploads, so check which command
        // is being processed.
        if (in_array($command->getName(), ['PutObject', 'CreateMultipartUpload'])) {
            // Set custom cache-control metadata.
            $command['CacheControl'] = 'max-age=3600';
            // Apply a canned ACL.
            $command['ACL'] = strpos($command['Key'], 'CONFIDENTIAL') ### false
                ? 'public-read'
                : 'private';
        }
    },
]);
```