Amazon S3 PHP SDK V2 & V3版上傳檔案使用範例



寫網站應用時「輸入」是很重要的一種操作,如何管理輸入的資料也是一門學問,檔案部分除了自己伺服器的檔案系統外還有一些雲儲存服務可以使用。

需求大致可以分為

  1. 減少網站伺服器因檔案傳輸而耗掉的頻寬
  2. 使用內容分散式網路(CDN)提升使用者讀取網站的速度
  3. 降低檔案儲存風險與提升系統安全(雞蛋不在同一個籃子裡的概念)

網路上有很多這種服務了,也都會提供一些方法來接入,怎麼選擇是看人,但不外乎就是「穩定性」與「價格」這兩個參數。

下面不多說,直接回到標題「使用實例」,因為協助廠商規劃流量型客製化系統,不過對口的工程師不太熟AWS S3這塊,就自己來摸一下寫個範例給他。

AWS S3 的 SDK 有兩個版本:

  1. V3 版SDK參考: 文件連結

  2. V2 版SDK參考: 文件連結

其中V3版有個需求是PHP版本要求要5.5以上,要注意!

我測試時的環境為: PHP 5.5.24 (cli) (built: May 19 2015 10:10:05)

安裝方式為直接到Github上抓目前最新的V3.2.4 & V2.8.17

分別下載到指定目錄後,新建php程式 v2_test.php & v3_test.php

V2 Code

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

use Aws\Common\Exception\MultipartUploadException;
use Aws\S3\Model\MultipartUpload\UploadBuilder;
use Aws\S3\S3Client;

$bucket = 'mxp-cloud-bucket';
$keyname = '/test/mxp.tw.jpg';

// Instantiate the client.
$s3 = S3Client::factory(array(
    'version'     => 'latest',
    'region'      => 'us-east-1',
    'key'    => 'YOUR_ACCESS_TOKEN',
    'secret' => 'YOUR_SECRET_TOKEN'
));

// Prepare the upload parameters.
$uploader = UploadBuilder::newInstance()
    ->setClient($s3)
    ->setSource('mxp.tw.jpg')
    ->setBucket($bucket)
    ->setKey($keyname)
    ->setMinPartSize(25 * 1024 * 1024)
    ->setOption('ACL', 'public-read')
    ->setConcurrency(3)
    ->build();

// Perform the upload. Abort the upload if something goes wrong.
try {
    $uploader->upload();
    echo "Upload complete.\n";
} catch (MultipartUploadException $e) {
    $uploader->abort();
    echo "Upload failed.\n";
    echo $e->getMessage() . "\n";
}

V3 Code

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

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

$bucket = 'mxp-cloud-bucket';
$keyname = 'test/mxp.tw_V2.jpg';

// Instantiate the client.
$s3 = new Aws\S3\S3Client([
    'version' => '2006-03-01',
    'region'  => 'us-east-1',
    'credentials' => [
        'key'    => 'YOUR_ACCESS_TOKEN',
        'secret' => 'YOUR_SECRET_TOKEN'
    ]
]);


// Prepare the upload parameters.
$source = 'mxp.tw.jpg';
$uploader = new MultipartUploader($s3, $source, [
    'bucket' => $bucket,
    'key'    => $keyname,
]);

// $promise = $uploader->promise();
// Perform the upload. Abort the upload if something goes wrong.
try {
    $uploader->upload();
    echo "Upload complete.\n";
} catch (MultipartUploadException $e) {
    $uploader->abort();
    echo "Upload failed.\n";
    echo $e->getMessage() . "\n";
}

寫法上有些微不同,但只要概念對就不難看出差異!

region的部分如果使用預設美國地區的話要填入us-east-1,這個倒是要注意一下,其他地區會在檔案的URL上看出端倪,而預設的話就只有s3.amazon.com這樣。

再來就是bucket設定是不用包含目錄的,目錄階層設定分開,這邊兩個範例是上傳同一個圖片檔,但指定不同目錄階層。

更多設定與功能可以參考SDK文件,都寫的還滿清楚了,有機會再寫設定IAM服務控制AWS服務權限的部分來掌控服務存取範圍吧!

btw, 在找對口工程師提到的錯誤「An exception occurred while initiating a multipart upload.」時,剛好看到有個issue提到在SDK第二版會有上傳檔案大小超過5GB發生錯誤的問題,相關開發者已列入Bug追查中,不過以目前規劃的架構,單檔要超過5GB應該是不會出現,所以還不是很大的影響。

Facebook 功能:

Share: