從 第 2 版遷移 適用於 PHP 的 AWS SDK - 適用於 PHP 的 AWS SDK

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

從 第 2 版遷移 適用於 PHP 的 AWS SDK

本主題說明如何遷移程式碼以使用 適用於 PHP 的 AWS SDK 第 3 版,並說明新版本與開發套件第 2 版的差異。

注意

開發套件第 2 版的基本使用模式 (如 $result = $client->operation($params);) 在第 3 版中並沒有變化,能讓使用者順利遷移版本。

簡介

第 3 版 適用於 PHP 的 AWS SDK 代表了改善 SDK 功能、納入超過兩年的客戶意見回饋、升級相依性、改善效能,以及採用最新 PHP 標準的重大努力。

第 3 版有哪些新功能?

第 3 版 適用於 PHP 的 AWS SDK 遵循 PSR-4 和 PSR-7 標準,並將遵循 SemVer 標準。

其他新功能包括:

  • 推出中介軟體系統,可用來自訂服務用戶端行為

  • 彈性化的分頁程式,可讓使用者逐一查看分頁結果

  • 能夠使用 JMESPath,從結果分頁程式物件中查詢資料

  • 藉由 'debug' 組態選項,即可輕鬆偵錯

分離式 HTTP 層級

  • 依據預設,系統會使用 Guzzle 6 傳送請求,但亦支援 Guzzle 5。

  • 系統將在無法使用 cURL 的環境中運作此開發套件。

  • 亦支援自訂 HTTP 處理常式。

非同步請求

  • 使用者亦可採用非同步的方式來執行等待程式分段上傳程式等功能。

  • 可以透過 promisescoroutines,建立非同步的工作流程。

  • 並行請求或批次請求的效能有所改善。

與第 2 版有何不同?

專案相依性已更新

此版本的開發套件相依性有所變更。

  • 開發套件現在需要 PHP 8.1+。除此之外,開發套件程式碼中亦大量地使用 generators (產生器)。

  • 我們已升級軟體開發套件以使用 Guzzle 6 (或 5),提供軟體開發套件用來將請求傳送至 AWS 服務的基礎 HTTP 用戶端實作。Guzzle 的最新版本推出許多改良功能,包括非同步請求、可切換的 HTTP 處理常式、PSR-7 規範,以及更優異的效能等等。

  • 來自 PHP-FIG (psr/http-message) 的 PSR-7 套件,成功定義了用來代表 HTTP 請求、HTTP 回應、URL 與串流的界面。這些界面可供開發套件與 Guzzle 使用,亦可與其他 PSR-7 合規套件保持互通性。

  • Guzzle 的 PSR-7 實作套件 (guzzlehttp/psr7) 提供了 PSR-7 中界面的實作,以及數種頗具助益的類別與函數。因此,不論是開發套件或是 Guzzle 6,都極度倚賴此套件。

  • 軟體開發套件與 Guzzle 皆使用 Guzzle 推出的 Promises/A+ 實作 (guzzlehttp/promises),以提供管理非同步請求和 coroutine 的界面。最終,Guzzle 的多重 cURL HTTP 處理器會實作非封鎖式 I/O 模型,允許非同步請求,且此套件可讓使用者在該模式中進行程式設計。如需詳細資訊,請參閱第 3 適用於 PHP 的 AWS SDK 版中的 Promises

  • 開發套件會採用 PHP 推出的 JMESPath 實作 (mtdowling/jmespath.php),以供使用者查詢 Aws\Result::search()Aws\ResultPaginator::search() 方法的資料。如需詳細資訊,請參閱第 3 適用於 PHP 的 AWS SDK 版中的 JMESPath 表達式

現在需要區域和版本選項

當您將任何服務的用戶端執行個體化時,請指定 'region''version' 選項。在 第 2 版中 適用於 PHP 的 AWS SDK, 'version' 是完全選用的,有時'region'是選用的。然而在第 3 版中,上述兩個選項一律為必要選項。明確說明這兩個選項可讓您鎖定要為其編碼的 API 版本和 AWS 區域。建立新的 API 版本或新的 AWS 區域可用時,系統會將您與可能中斷的變更隔離,直到您準備好明確更新組態為止。

注意

如果您對使用中的 API 版本沒有疑慮,則僅需將 'version' 選項設為 'latest'。不過,我們建議您明確地設定生產程式碼的 API 版本編號。

並非所有 服務都適用於所有 AWS 區域。如需查詢可用區域的清單,請參考區域與端點

對於只能透過單一全域端點 (例如 Amazon Route 53、 和 Amazon CloudFront) 提供的服務 AWS Identity and Access Management,請將用戶端的已設定區域設定為 來執行個體化us-east-1

重要

SDK 也包含多區域用戶端,可根據做為命令參數提供的參數 (@region),將請求分派至不同的 AWS 區域。這些用戶端預設使用的區域是經由提供給用戶端建構函式的 region 選項加以指定。

用戶端執行個體化使用 建構函數

在 第 3 版中 適用於 PHP 的 AWS SDK,您執行個體化用戶端的方式已變更。您僅需使用 factory 關鍵字,即可將用戶端執行個體化,不需再使用第 2 版的 new 方法。

use Aws\DynamoDb\DynamoDbClient; // Version 2 style $client = DynamoDbClient::factory([ 'region' => 'us-east-2' ]); // Version 3 style $client = new DynamoDbClient([ 'region' => 'us-east-2', 'version' => '2012-08-10' ]);
注意

您依然可以使用 factory() 方法來執行個體化用戶端。不過,系統會將該方式視為已遭取代。

用戶端組態已變更

第 3 版中的用戶端組態選項已從第 2 版稍微 適用於 PHP 的 AWS SDK 變更。如需所有支援選項的說明,請參閱第 3 適用於 PHP 的 AWS SDK 版的組態頁面。

重要

在第 3 版的根層級中,'key''secret' 不再是有效的選項,但您可以將這兩個選項傳入 'credentials' 選項。我們這麼做的其中一個原因是阻止開發人員將 AWS 登入資料硬式編碼到專案中。

Sdk 物件

第 3 版會將 Aws\Sdk 物件做為替代項目 適用於 PHP 的 AWS SDK 引入 Aws\Common\Aws。系統會將 Sdk 物件做為用戶端 factory 使用,並採用該物件來管理多個用戶端的共用組態選項。

雖然軟體開發套件第 2 版的 Aws 類別是以類似服務定位器的方式進行運作 (該類別會一律傳回相同的用戶端執行個體),但第 3 版的 Sdk 類別每次都會傳回新的用戶端執行個體。

Sdk 物件亦不支援與軟體開發套件第 2 版相同的組態檔案格式。該組態格式為 Guzzle 3 專屬格式,目前已淘汰。使用基本陣列將能更輕鬆地進行組態,其做法詳載於使用 Sdk 類別

某些 API 結果已變更

為了提供 SDK 如何剖析 API 操作結果的一致性,Amazon ElastiCache、Amazon RDS 和 Amazon Redshift 現在在某些 API 回應上具有額外的包裝元素。

例如,呼叫 Amazon RDS DescribeEngineDefaultParameters 會導致版本 3 現在包含包裝 “EngineDefaults” 元素。然而在第 2 版中,此元素並不存在。

$client = new Aws\Rds\RdsClient([ 'region' => 'us-west-1', 'version' => '2014-09-01' ]); // Version 2 $result = $client->describeEngineDefaultParameters(); $family = $result['DBParameterGroupFamily']; $marker = $result['Marker']; // Version 3 $result = $client->describeEngineDefaultParameters(); $family = $result['EngineDefaults']['DBParameterGroupFamily']; $marker = $result['EngineDefaults']['Marker'];

下列操作在此版本中亦受到影響,因此這些操作目前在輸出結果中會納入包裝元素,如括號中所示:

  • Amazon ElastiCache

    • AuthorizeCacheSecurityGroupIngress (CacheSecurityGroup)

    • CopySnapshot (Snapshot)

    • CreateCacheCluster (CacheCluster)

    • CreateCacheParameterGroup (CacheParameterGroup)

    • CreateCacheSecurityGroup (CacheSecurityGroup)

    • CreateCacheSubnetGroup (CacheSubnetGroup)

    • CreateReplicationGroup (ReplicationGroup)

    • CreateSnapshot (Snapshot)

    • DeleteCacheCluster (CacheCluster)

    • DeleteReplicationGroup (ReplicationGroup)

    • DeleteSnapshot (Snapshot)

    • DescribeEngineDefaultParameters (EngineDefaults)

    • ModifyCacheCluster (CacheCluster)

    • ModifyCacheSubnetGroup (CacheSubnetGroup)

    • ModifyReplicationGroup (ReplicationGroup)

    • PurchaseReservedCacheNodesOffering (ReservedCacheNode)

    • RebootCacheCluster (CacheCluster)

    • RevokeCacheSecurityGroupIngress (CacheSecurityGroup)

  • Amazon RDS

    • AddSourceIdentifierToSubscription (EventSubscription)

    • AuthorizeDBSecurityGroupIngress (DBSecurityGroup)

    • CopyDBParameterGroup (DBParameterGroup)

    • CopyDBSnapshot (DBSnapshot)

    • CopyOptionGroup (OptionGroup)

    • CreateDBInstance (DBInstance)

    • CreateDBInstanceReadReplica (DBInstance)

    • CreateDBParameterGroup (DBParameterGroup)

    • CreateDBSecurityGroup (DBSecurityGroup)

    • CreateDBSnapshot (DBSnapshot)

    • CreateDBSubnetGroup (DBSubnetGroup)

    • CreateEventSubscription (EventSubscription)

    • CreateOptionGroup (OptionGroup)

    • DeleteDBInstance (DBInstance)

    • DeleteDBSnapshot (DBSnapshot)

    • DeleteEventSubscription (EventSubscription)

    • DescribeEngineDefaultParameters (EngineDefaults)

    • ModifyDBInstance (DBInstance)

    • ModifyDBSubnetGroup (DBSubnetGroup)

    • ModifyEventSubscription (EventSubscription)

    • ModifyOptionGroup (OptionGroup)

    • PromoteReadReplica (DBInstance)

    • PurchaseReservedDBInstancesOffering (ReservedDBInstance)

    • RebootDBInstance (DBInstance)

    • RemoveSourceIdentifierFromSubscription (EventSubscription)

    • RestoreDBInstanceFromDBSnapshot (DBInstance)

    • RestoreDBInstanceToPointInTime (DBInstance)

    • RevokeDBSecurityGroupIngress (DBSecurityGroup)

  • Amazon Redshift

    • AuthorizeClusterSecurityGroupIngress (ClusterSecurityGroup)

    • AuthorizeSnapshotAccess (Snapshot)

    • CopyClusterSnapshot (Snapshot)

    • CreateCluster (Cluster)

    • CreateClusterParameterGroup (ClusterParameterGroup)

    • CreateClusterSecurityGroup (ClusterSecurityGroup)

    • CreateClusterSnapshot (Snapshot)

    • CreateClusterSubnetGroup (ClusterSubnetGroup)

    • CreateEventSubscription (EventSubscription)

    • CreateHsmClientCertificate (HsmClientCertificate)

    • CreateHsmConfiguration (HsmConfiguration)

    • DeleteCluster (Cluster)

    • DeleteClusterSnapshot (Snapshot)

    • DescribeDefaultClusterParameters (DefaultClusterParameters)

    • DisableSnapshotCopy (Cluster)

    • EnableSnapshotCopy (Cluster)

    • ModifyCluster (Cluster)

    • ModifyClusterSubnetGroup (ClusterSubnetGroup)

    • ModifyEventSubscription (EventSubscription)

    • ModifySnapshotCopyRetentionPeriod (Cluster)

    • PurchaseReservedNodeOffering (ReservedNode)

    • RebootCluster (Cluster)

    • RestoreFromClusterSnapshot (Cluster)

    • RevokeClusterSecurityGroupIngress (ClusterSecurityGroup)

    • RevokeSnapshotAccess (Snapshot)

    • RotateEncryptionKey (Cluster)

列舉類別已移除

我們已經移除 適用於 PHP 的 AWS SDK第 2 版現存的 Enum 類別 (如 Aws\S3\Enum\CannedAcl)。Enum 屬於開發套件公有 API 中的具體類別,而該類別所含的常數可用來表示有效參數值群組。由於這些 enum 是 API 版本特有的類別,可能會隨著時間改變,或是與 PHP 保留字衝突,致使降低效能且沒有任何助益;因此,我們決定在第 3 版中移除這些類別。如此一來,這項改變即可支援第 3 版的資料導向與 API 版本適用性。

您不該使用來自 Enum 物件的值,而是直接使用常值。例如:使用 CannedAcl::PUBLIC_READ 取代 'public-read'

已移除精細的例外類別

出於與移除 Enums 類別相似的考量,我們也一併移除了各服務命名空間中的精細例外狀況類別 (例如 Aws\Rds\Exception\{SpecificError}Exception)。由於服務或操作會依據使用的 API 版本來擲出例外狀況,因此例外狀況會隨版本而異。不僅如此,系統亦無法使用指定操作所拋出的例外狀況完整清單,導致第 2 版的精細例外狀況類別無法完整呈現。

為了處理錯誤,您應該取得各項服務的例外根類別 (例如:Aws\Rds\Exception\RdsException)。您可以使用例外狀況的 getAwsErrorCode() 方法,藉此檢查特定的錯誤碼。此功能相當於取得不同的例外類別,但本版本所提供的功能不會增加開發套件的膨脹速度。

靜態外觀類別已移除

在 第 2 版中 適用於 PHP 的 AWS SDK,有一個受到 Laravel 啟發的隱藏功能,可讓您在 Aws類別enableFacades()上呼叫 ,以啟用對各種服務用戶端的靜態存取。然而,這項功能並不符合 PHP 最佳實務。因此,我們在一年前便已經停止記錄該功能,而我們更是在第 3 版中完全將之移除。從 Aws\Sdk 物件中擷取用戶端物件,並將這些物件做為物件執行個體來使用,而非靜態類別。

分頁程式取代疊代運算

第 2 版 適用於 PHP 的 AWS SDK 具有名為 * 迭代器* 的功能。系統會使用疊代運算物件來逐一查看分頁結果。使用者對這些物件感到不滿的原因之一便是「缺乏彈性」,因為疊代運算僅會發送每個結果的特定值。您只能透過事件接聽程式,才能擷取其他所需的結果值。

在第 3 版中,疊代運算已由分頁程式取代。兩種功能的用途十分相似,但分頁程式提供更多使用彈性。這是因為分頁程式會產生結果物件,而非擷取回應中的數值。

以下範例會示範第 2 版和第 3 版如何擷取 S3 ListObjects 操作的分頁結果,以便說明分頁程式與疊代運算之間的差異。

// Version 2 $objects = $s3Client->getIterator('ListObjects', ['Bucket' => 'amzn-s3-demo-bucket']); foreach ($objects as $object) { echo $object['Key'] . "\n"; }
// Version 3 $results = $s3Client->getPaginator('ListObjects', ['Bucket' => 'amzn-s3-demo-bucket']); foreach ($results as $result) { // You can extract any data that you want from the result. foreach ($result['Contents'] as $object) { echo $object['Key'] . "\n"; } }

分頁程式物件的 search() 方法讓您能夠使用 JMESPath 表達式,更輕鬆地從結果集擷取資料。

$results = $s3Client->getPaginator('ListObjects', ['Bucket' => 'amzn-s3-demo-bucket']); foreach ($results->search('Contents[].Key') as $key) { echo $key . "\n"; }
注意

為了讓使用者順利轉移至第 3 版,該版本仍然支援 getIterator() 方法,但我們建議您遷移程式碼以使用分頁程式。

許多更高層級的抽象概念已變更

整體而言,此版本改良或更新了許多高階抽象概念 (除用戶端之外的服務特定 helper 物件);甚至移除部分高階抽象概念。

比較兩種 SDK 版本的程式碼範例

下列範例顯示使用 第 3 適用於 PHP 的 AWS SDK 版與第 2 版的一些不同之處。

範例:Amazon S3 ListObjects操作

從 SDK 第 2 版開始

<?php require '/path/to/vendor/autoload.php'; use Aws\S3\S3Client; use Aws\S3\Exception\S3Exception; $s3 = S3Client::factory([ 'profile' => 'my-credential-profile', 'region' => 'us-east-1' ]); try { $result = $s3->listObjects([ 'Bucket' => 'amzn-s3-demo-bucket', 'Key' => 'my-object-key' ]); foreach ($result['Contents'] as $object) { echo $object['Key'] . "\n"; } } catch (S3Exception $e) { echo $e->getMessage() . "\n"; }

從 SDK 第 3 版

主要差異:

  • 使用 new 將用戶端執行個體化,而非使用 factory()

  • 需要指定 'version''region' 選項,才能執行個體化。

<?php require '/path/to/vendor/autoload.php'; use Aws\S3\S3Client; use Aws\S3\Exception\S3Exception; $s3 = new S3Client([ 'profile' => 'my-credential-profile', 'region' => 'us-east-1', 'version' => '2006-03-01' ]); try { $result = $s3->listObjects([ 'Bucket' => 'amzn-s3-demo-bucket', 'Key' => 'my-object-key' ]); foreach ($result['Contents'] as $object) { echo $object['Key'] . "\n"; } } catch (S3Exception $e) { echo $e->getMessage() . "\n"; }

範例:使用全域組態執行個體化用戶端

從 SDK 第 2 版開始

<?php return array( 'includes' => array('_aws'), 'services' => array( 'default_settings' => array( 'params' => array( 'profile' => 'my_profile', 'region' => 'us-east-1' ) ), 'dynamodb' => array( 'extends' => 'dynamodb', 'params' => array( 'region' => 'us-west-2' ) ), ) );
<?php require '/path/to/vendor/autoload.php'; use Aws\Common\Aws; $aws = Aws::factory('path/to/my/config.php'); $sqs = $aws->get('sqs'); // Note: SQS client will be configured for us-east-1. $dynamodb = $aws->get('dynamodb'); // Note: DynamoDB client will be configured for us-west-2.

從 SDK 第 3 版

主要差異:

  • 使用 Aws\Sdk 類別,而不是 Aws\Common\Aws

  • 沒有組態檔案。但會使用組態陣列取而代之。

  • 需要指定 'version' 選項,才能執行個體化。

  • 使用 create<Service>() 方法,而不是 get('<service>')

<?php require '/path/to/vendor/autoload.php'; $sdk = new Aws\Sdk([ 'profile' => 'my_profile', 'region' => 'us-east-1', 'version' => 'latest', 'DynamoDb' => [ 'region' => 'us-west-2', ], ]); $sqs = $sdk->createSqs(); // Note: Amazon SQS client will be configured for us-east-1. $dynamodb = $sdk->createDynamoDb(); // Note: DynamoDB client will be configured for us-west-2.