本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
將 Amazon S3 分段上傳與 AWS SDK for PHP 版本 3 搭配使用
透過單次 PutObject
操作,您最多可上傳大小 5 GB 的物件。不過,如果使用分段上傳方法 (例如,CreateMultipartUpload
、UploadPart
、CompleteMultipartUpload
、AbortMultipartUpload
),您可以上傳大小從 5 MB 到 5 TB 的物件。
下列範例將說明:
-
使用 ObjectUploader 將物件上傳至 Amazon S3。
-
使用 MultipartUploader 為 Amazon S3 物件建立分段上傳。
-
使用 Word 將物件從一個 Amazon S3 位置複製到另一個位置。 ObjectCopier
所有 的範例程式碼 AWS SDK for PHP 都可在 GitHub 上取得
登入資料
在執行範例程式碼之前,請先設定您的 AWS 憑證,如 中所述憑證。然後匯入 AWS SDK for PHP,如 中所述基本使用。
物件上傳程式
如果您不確定 PutObject
或 MultipartUploader
是否最適合任務,請使用 ObjectUploader
。 會根據承載大小MultipartUploader
,使用 PutObject
或 將大型檔案ObjectUploader
上傳至 Amazon S3。
require 'vendor/autoload.php'; use Aws\Exception\MultipartUploadException; use Aws\S3\MultipartUploader; use Aws\S3\ObjectUploader; use Aws\S3\S3Client;
範例程式碼
// Create an S3Client. $s3Client = new S3Client([ 'profile' => 'default', 'region' => 'us-east-2', 'version' => '2006-03-01' ]); $bucket = 'your-bucket'; $key = 'my-file.zip'; // Use a stream instead of a file path. $source = fopen('/path/to/large/file.zip', 'rb'); $uploader = new ObjectUploader( $s3Client, $bucket, $key, $source ); do { try { $result = $uploader->upload(); if ($result["@metadata"]["statusCode"] == '200') { print('<p>File successfully uploaded to ' . $result["ObjectURL"] . '.</p>'); } print($result); // If the SDK chooses a multipart upload, try again if there is an exception. // Unlike PutObject calls, multipart upload calls are not automatically retried. } catch (MultipartUploadException $e) { rewind($source); $uploader = new MultipartUploader($s3Client, $source, [ 'state' => $e->getState(), ]); } } while (!isset($result)); fclose($source);
組態
ObjectUploader
物件建構函式接受下列引數:
$client
-
用來執行傳輸的
Aws\ClientInterface
物件。這應該是Aws\S3\S3Client
的執行個體。 $bucket
-
(
string
,必要) 做為物件上傳目的地的儲存貯體的名稱。 $key
-
(
string
,必要) 待上傳的物件所要使用的金鑰。 $body
-
(
mixed
,需要) 要上傳的物件資料。可以是StreamInterface
、PHP 串流資源或要上傳的資料字串。 $acl
-
(
string
) 存取控制清單 (ACL),以在要上傳的物件上設定。物件預設為私有。 $options
-
分段上傳的組態選項的關聯式陣列。下列組態選項為有效:
add_content_md5
-
(
bool
) 設為 true 可自動計算上傳的 MD5 檢查總和。 mup_threshold
-
(
int
,預設:int(16777216)
) 檔案大小的位元組數。如果檔案大小超過此限制,則會使用分段上傳。 before_complete
-
(
callable
) 要在CompleteMultipartUpload
操作之前呼叫的回呼函式。回呼應具有類似 的函數簽章:function (Aws\Command $command) {...}
。如需可新增至CommandInterface
物件的參數,請參閱 CompleteMultipartUpload API Word參考。 before_initiate
-
(
callable
) 要在CreateMultipartUpload
操作之前呼叫的回呼函式。回呼應具有類似 的函數簽章:function (Aws\Command $command) {...}
。如果檔案大小超過mup_threshold
值,SDK 會叫用此回呼。如需可新增至CommandInterface
物件的參數,請參閱 CreateMultipartUpload API Word參考。 before_upload
-
(
callable
) 回撥以在任何PutObject
或UploadPart
操作之前叫用 。回呼應具有類似 的函數簽章:function (Aws\Command $command) {...}
。如果檔案大小小於或等於mup_threshold
值,SDK 會叫用此回呼。如需可套用至PutObject
請求的參數,請參閱 PutObject API Word參考。如需套用至UploadPart
請求的參數,請參閱 UploadPart API Word參考。SDK 會忽略任何不適用於CommandInterface
物件所代表操作的參數。 concurrency
-
(
int
,預設:int(3)
) 分段上傳期間所允許的並行UploadPart
操作的數目上限。 part_size
-
(
int
,預設:int(5242880)
) 進行分段上傳時所使用的分段大小 (位元組)。該值必須介於 5 MB 到 5 GB 之間,包括 。 state
-
(
Aws\Multipart\UploadState
) 代表分段上傳狀態的物件,用來恢復先前的上傳作業。提供此選項時,會忽略$bucket
和$key
引數和part_size
選項。 params
-
為每個子命令提供組態選項的關聯陣列。例如:
new ObjectUploader($bucket, $key, $body, $acl, ['params' => ['CacheControl' =>
<some_value>
])
MultipartUploader
分段上傳是專為改善較大型物件上傳的體驗所設計。這些方法可讓您以任意順序,個別同時上傳物件的各部分。
建議 Amazon S3 客戶針對大於 100 MB 的物件使用分段上傳。
MultipartUploader 物件
SDK 具有特殊MultipartUploader
物件,可簡化分段上傳程序。
匯入
require 'vendor/autoload.php'; use Aws\Exception\MultipartUploadException; use Aws\S3\MultipartUploader; use Aws\S3\S3Client;
範例程式碼
$s3Client = new S3Client([ 'profile' => 'default', 'region' => 'us-west-2', 'version' => '2006-03-01' ]); // Use multipart upload $source = '/path/to/large/file.zip'; $uploader = new MultipartUploader($s3Client, $source, [ 'bucket' => 'your-bucket', 'key' => 'my-file.zip', ]); try { $result = $uploader->upload(); echo "Upload complete: {$result['ObjectURL']}\n"; } catch (MultipartUploadException $e) { echo $e->getMessage() . "\n"; }
上傳程式會根據隨附的原始碼和組態,建立分段資料的產生器,並嘗試上傳所有部分。如果某些部分上傳失敗,上傳程式會持續上傳之後的部分,直到讀取完整個原始碼的資料。之後,上傳工具會嘗試上傳失敗的部分,或擲出包含與無法上傳之部分相關資訊的例外狀況。
自訂分段上傳
您可以透過將回呼函式傳遞至其建構函式,來針對多段上傳程式所執行的 CreateMultipartUpload
、UploadPart
與 CompleteMultipartUpload
操作,設定自訂選項。
匯入
require 'vendor/autoload.php'; use Aws\S3\MultipartUploader; use Aws\S3\S3Client;
範例程式碼
// Create an S3Client $s3Client = new S3Client([ 'profile' => 'default', 'region' => 'us-west-2', 'version' => '2006-03-01' ]); // Customizing a multipart upload $source = '/path/to/large/file.zip'; $uploader = new MultipartUploader($s3Client, $source, [ 'bucket' => 'your-bucket', 'key' => 'my-file.zip', 'before_initiate' => function (Command $command) { // $command is a CreateMultipartUpload operation $command['CacheControl'] = 'max-age=3600'; }, 'before_upload' => function (Command $command) { // $command is an UploadPart operation $command['RequestPayer'] = 'requester'; }, 'before_complete' => function (Command $command) { // $command is a CompleteMultipartUpload operation $command['RequestPayer'] = 'requester'; }, ]);
部分上傳之間的手動垃圾收集
如果您使用大型上傳達到記憶體限制,這可能是因為 SDK 垃圾收集器在達到記憶體限制時尚未收集到 PHP
$uploader = new MultipartUploader($client, $source, [ 'bucket' => 'your-bucket', 'key' => 'your-key', 'before_upload' => function(\Aws\Command $command) { gc_collect_cycles(); } ]);
從錯誤中復原
在分段上傳過程中發生錯誤時,會丟出 MultipartUploadException
。此例外狀況提供了對 UploadState
物件的存取,而此物件包含關於分段上傳進度的資訊。UploadState
可用來恢復無法完成的上傳作業。
匯入
require 'vendor/autoload.php'; use Aws\Exception\MultipartUploadException; use Aws\S3\MultipartUploader; use Aws\S3\S3Client;
範例程式碼
// Create an S3Client $s3Client = new S3Client([ 'profile' => 'default', 'region' => 'us-west-2', 'version' => '2006-03-01' ]); $source = '/path/to/large/file.zip'; $uploader = new MultipartUploader($s3Client, $source, [ 'bucket' => 'your-bucket', 'key' => 'my-file.zip', ]); //Recover from errors do { try { $result = $uploader->upload(); } catch (MultipartUploadException $e) { $uploader = new MultipartUploader($s3Client, $source, [ 'state' => $e->getState(), ]); } } while (!isset($result)); //Abort a multipart upload if failed try { $result = $uploader->upload(); } catch (MultipartUploadException $e) { // State contains the "Bucket", "Key", and "UploadId" $params = $e->getState()->getId(); $result = $s3Client->abortMultipartUpload($params); }
透過 UploadState
恢復上傳的動作時,會嘗試上傳尚未上傳的部分。狀態物件會追蹤缺少的部分,即使這些部分並不連續。上傳程式會針對所提供的原始碼檔案,讀取或搜尋屬於仍需上傳部分的位元組範圍,
UploadState
物件可序列化,因此您也可以在不同的程序中恢復上傳。即使不是在處理例外狀況時,您也可以透過呼叫 $uploader->getState()
,來取得 UploadState
物件。
重要
做為資源傳遞到 MultipartUploader
的串流,在上傳之前不會自動跳回開頭。如果您使用的是串流,而非類似於先前範例中迴圈內的檔案路徑,則請重設 catch
區塊中的 $source
變數。
匯入
require 'vendor/autoload.php'; use Aws\Exception\MultipartUploadException; use Aws\S3\MultipartUploader; use Aws\S3\S3Client;
範例程式碼
// Create an S3Client $s3Client = new S3Client([ 'profile' => 'default', 'region' => 'us-west-2', 'version' => '2006-03-01' ]); //Using stream instead of file path $source = fopen('/path/to/large/file.zip', 'rb'); $uploader = new MultipartUploader($s3Client, $source, [ 'bucket' => 'your-bucket', 'key' => 'my-file.zip', ]); do { try { $result = $uploader->upload(); } catch (MultipartUploadException $e) { rewind($source); $uploader = new MultipartUploader($s3Client, $source, [ 'state' => $e->getState(), ]); } } while (!isset($result)); fclose($source);
中止分段上傳
您可以擷取 UploadState
物件中包含的 UploadId
,並將它傳遞至 abortMultipartUpload
,以中止分段上傳。
try { $result = $uploader->upload(); } catch (MultipartUploadException $e) { // State contains the "Bucket", "Key", and "UploadId" $params = $e->getState()->getId(); $result = $s3Client->abortMultipartUpload($params); }
非同步分段上傳
呼叫 upload()
的 MultipartUploader
是封鎖請求。如果是在非同步的情境中作業,您可以取得分段上傳的 promise 物件。
require 'vendor/autoload.php'; use Aws\S3\MultipartUploader; use Aws\S3\S3Client;
範例程式碼
// Create an S3Client $s3Client = new S3Client([ 'profile' => 'default', 'region' => 'us-west-2', 'version' => '2006-03-01' ]); $source = '/path/to/large/file.zip'; $uploader = new MultipartUploader($s3Client, $source, [ 'bucket' => 'your-bucket', 'key' => 'my-file.zip', ]); $promise = $uploader->promise();
組態
MultipartUploader
物件建構函式接受下列引數:
-
$client
-
用來執行傳輸的
Aws\ClientInterface
物件。這應該是Aws\S3\S3Client
的執行個體。 -
$source
-
正在上傳的原始碼資料。這可以是路徑或 URL (例如
/path/to/file.jpg
)、資源處理常式 (例如fopen('/path/to/file.jpg', 'r)
) 或 PSR-7 串流的執行個體。 -
$config
-
分段上傳的組態選項的關聯式陣列。
下列組態選項為有效:
-
acl
-
(
string
) 存取控制清單 (ACL),以在要上傳的物件上設定。物件預設為私有。 -
before_complete
-
(
callable
) 要在CompleteMultipartUpload
操作之前呼叫的回呼函式。回呼函式應具有像是function (Aws\Command $command) {...}
的函式簽章。 -
before_initiate
-
(
callable
) 要在CreateMultipartUpload
操作之前呼叫的回呼函式。回呼函式應具有像是function (Aws\Command $command) {...}
的函式簽章。 -
before_upload
-
(
callable
) 要在任何UploadPart
操作之前呼叫的回呼函式。回呼函式應具有像是function (Aws\Command $command) {...}
的函式簽章。 -
bucket
-
(
string
,必要) 做為物件上傳目的地的儲存貯體的名稱。 -
concurrency
-
(
int
,預設:int(5)
) 分段上傳期間所允許的並行UploadPart
操作的數目上限。 -
key
-
(
string
,必要) 待上傳的物件所要使用的金鑰。 -
part_size
-
(
int
,預設:int(5242880)
) 進行分段上傳時所使用的分段大小 (位元組)。這必須介於 5 MB 到 5 GB 之間 (含)。 -
state
-
(
Aws\Multipart\UploadState
) 代表分段上傳狀態的物件,用來恢復先前的上傳作業。提供此選項時,會略過bucket
、key
和part_size
選項。 add_content_md5
-
(
boolean
) 設為 true 可自動計算上傳的 MD5 檢查總和。 params
-
為每個子命令提供組態選項的關聯陣列。例如:
new MultipartUploader($client, $source, ['params' => ['CacheControl' =>
<some_value>
]])
-
分段副本
AWS SDK for PHP 也包含一個MultipartCopy
物件,其使用方式與 類似MultipartUploader
,但設計用於在 Amazon S3 內複製大小介於 5 GB 到 5 TB 之間的物件。
require 'vendor/autoload.php'; use Aws\Exception\MultipartUploadException; use Aws\S3\MultipartCopy; use Aws\S3\S3Client;
範例程式碼
// Create an S3Client $s3Client = new S3Client([ 'profile' => 'default', 'region' => 'us-west-2', 'version' => '2006-03-01' ]); //Copy objects within S3 $copier = new MultipartCopy($s3Client, '/bucket/key?versionId=foo', [ 'bucket' => 'your-bucket', 'key' => 'my-file.zip', ]); try { $result = $copier->copy(); echo "Copy complete: {$result['ObjectURL']}\n"; } catch (MultipartUploadException $e) { echo $e->getMessage() . "\n"; }