

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

# 搭配第 3 適用於 PHP 的 AWS SDK 版使用 DynamoDB 工作階段處理常式
<a name="service_dynamodb-session-handler"></a>

DynamoDB 工作階段處理常式是 PHP 的自訂工作階段處理常式，可讓開發人員使用 Amazon DynamoDB 做為工作階段存放區。使用 DynamoDB 儲存工作階段，透過將工作階段從本機檔案系統移出並移至共用位置，來緩解分散式 Web 應用程式中工作階段處理所發生的問題。DynamoDB 快速、可擴展、易於設定，並自動處理資料的複寫。

DynamoDB 工作階段處理常式使用 `session_set_save_handler()`函數將 DynamoDB 操作掛鉤至 PHP 的[原生工作階段函數](http://www.php.net/manual/en/ref.session.php)，以允許真正捨棄取代。這包括功能的支援 (例如，工作階段鎖定和廢棄項目收集等功能)，這是 PHP 預設工作階段處理器的一部分。

如需 DynamoDB 服務的詳細資訊，請參閱 [Amazon DynamoDB 首頁](https://aws.amazon.com/dynamodb/)。

## 基本使用
<a name="basic-usage"></a>

### 步驟 1：註冊處理常式
<a name="step-1-register-the-handler"></a>

首先，將處理常式執行個體化，並進行登錄。

```
use Aws\DynamoDb\SessionHandler;

$dynamoDb = new Aws\DynamoDb\DynamoDbClient([
    'region'=>'us-east-1'  // Since version 3.277.10 of the SDK, 
]);                        // the 'version' parameter defaults to 'latest'.

$sessionHandler = SessionHandler::fromClient($dynamoDb, [
    'table_name' => 'sessions'
]);

$sessionHandler->register();
```

### 步驟 2. 建立資料表以存放您的工作階段
<a name="create-a-table-for-storing-your-sessions"></a>

您必須先建立資料表來儲存工作階段，然後才能實際地使用工作階段處理常式。您可以使用適用於 [AWS Amazon DynamoDB 的主控台](https://console.aws.amazon.com/dynamodb/home)，或使用 來提前執行此操作 適用於 PHP 的 AWS SDK。

建立此表格時，請使用 ‘id’ 做為主索引鍵的名稱。同時建議您使用 ‘expires’ 屬性來設定[存活期屬性](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/TTL.html)，以受益於工作階段的自動廢棄項目集合。

### 步驟 3。像平常一樣使用 PHP 工作階段
<a name="step-3-use-php-sessions-as-you-normally-would"></a>

工作階段處理器註冊完畢後，若資料表存在，您可以使用 `$_SESSION` 超全域 (superglobal) 寫入和讀取該工作階段，其方式與您一般對 PHP 預設工作階段處理器執行的作業相同。DynamoDB 工作階段處理常式會封裝和抽象與 DynamoDB 的互動，並可讓您直接使用 PHP 的原生工作階段函數和界面。

```
// Start the session
session_start();

// Alter the session data
$_SESSION['user.name'] = 'jeremy';
$_SESSION['user.role'] = 'admin';

// Close the session (optional, but recommended)
session_write_close();
```

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

您可以使用下列選項來設定工作階段處理常式的動作。所有選項皆為選用，但務必了解選項的預設值。

** `table_name` **  
要存放工作階段的 DynamoDB 資料表名稱。預設值為 `'sessions'`。

** `hash_key` **  
DynamoDB 工作階段資料表中的雜湊索引鍵名稱。預設值為 `'id'`。

** `data_attribute` **  
DynamoDB 工作階段資料表中存放工作階段資料的屬性名稱。預設值為 `'data'`。

** `data_attribute_type` **  
DynamoDB 工作階段資料表中存放工作階段資料的屬性類型。此值預設為 `'string'`，但可以選擇性地設定為 `'binary'`。

** `session_lifetime` **  
在應該進行垃圾收集之前，非作用中工作階段的存留期。若未提供此值，將會使用的實際生命週期為 `ini_get('session.gc_maxlifetime')`。

** `session_lifetime_attribute` **  
DynamoDB 工作階段資料表中存放工作階段過期時間的屬性名稱。預設值為 `'expires'`。

** `consistent_read` **  
工作階段處理常式是否應針對 `GetItem` 操作，使用一致性讀取。預設值為 `true`。

** `locking` **  
是否使用工作階段鎖定。預設值為 `false`。

** `batch_config` **  
用來在收集垃圾時進行批次刪除的設定。這些選項會直接傳入 [DynamoDB WriteRequestBatch](https://docs.aws.amazon.com/aws-sdk-php/v3/api/class-Aws.DynamoDb.WriteRequestBatch.html) 物件。透過 `SessionHandler::garbageCollect()`，以手動方式觸發廢棄項目收集作業。

** `max_lock_wait_time` **  
在放棄之前，工作階段處理常式應等待以取得鎖定的時間長度上限 (以秒為單位)。預設值為 `10`，而且只用於工作階段鎖定。

** `min_lock_retry_microtime` **  
工作階段處理常式應等待以嘗試取得鎖定的最短間隔時間 (以微秒為單位)。預設值為 `10000`，而且只用於工作階段鎖定。

** `max_lock_retry_microtime` **  
工作階段處理常式應等待以嘗試取得鎖定的最長間隔時間 (以微秒為單位)。預設值為 `50000`，而且只用於工作階段鎖定。

若要設定工作階段處理常式，在進行處理常式的執行個體化時，指定設定選項。下列的程式碼提供了範例，其中指定了所有的設定選項。

```
$sessionHandler = SessionHandler::fromClient($dynamoDb, [
    'table_name'                    => 'sessions',
    'hash_key'                      => 'id',
    'data_attribute'                => 'data',
    'data_attribute_type'           => 'string',
    'session_lifetime'              => 3600,
    'session_lifetime_attribute'    => 'expires',
    'consistent_read'               => true,
    'locking'                       => false,
    'batch_config'                  => [],
    'max_lock_wait_time'            => 10,
    'min_lock_retry_microtime'      => 5000,
    'max_lock_retry_microtime'      => 50000,
]);
```

## 定價
<a name="pricing"></a>

除了資料儲存和資料傳輸費用之外，使用 DynamoDB 的相關費用是根據資料表的佈建輸送量容量計算 （請參閱 [Amazon DynamoDB 定價詳細資訊](https://aws.amazon.com/dynamodb/pricing/))。傳輸量是以寫入容量和讀取容量的單位來測量。Amazon DynamoDB 首頁顯示：

讀取容量的單位，代表針對大小為 4 KB 的項目，每秒一次強式一致性讀取 (或是每秒 2 次最終一致讀取)。寫入容量的單位，代表針對大小為 1 KB 的項目，每秒一次寫入。

最後，您的工作階段資料表所需的傳輸量和成本，將會與您所預期的傳輸流量和工作階段大小相關。下表說明每個工作階段函數在 DynamoDB 資料表上執行的讀取和寫入操作量。


****  

|  |  | 
| --- |--- |
|  透過 `session_start()` 讀取   |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/sdk-for-php/v3/developer-guide/service_dynamodb-session-handler.html)  | 
|  透過 `session_start()` 讀取 (使用工作階段鎖定)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/sdk-for-php/v3/developer-guide/service_dynamodb-session-handler.html)  | 
|  透過 `session_write_close()` 寫入   |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/sdk-for-php/v3/developer-guide/service_dynamodb-session-handler.html)  | 
|  透過 `session_destroy()` 刪除   |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/sdk-for-php/v3/developer-guide/service_dynamodb-session-handler.html)  | 
|  垃圾收集  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/sdk-for-php/v3/developer-guide/service_dynamodb-session-handler.html)  | 

## 工作階段鎖定
<a name="ddbsh-session-locking"></a>

DynamoDB 工作階段處理常式支援漸進式工作階段鎖定，以模擬 PHP 預設工作階段處理常式的行為。根據預設，DynamoDB 工作階段處理常式會*關閉*此功能，因為它可能會成為效能瓶頸並增加成本，尤其是當應用程式在使用 Ajax 請求或 iframe 時存取工作階段時。請先仔細考慮您的應用程式是否需要工作階段鎖定功能，然後再啟用。

若要啟用工作階段鎖定，請在您進行 `'locking'` 的執行個體化時，將 `true` 選項設定為 `SessionHandler`。

```
$sessionHandler = SessionHandler::fromClient($dynamoDb, [
    'table_name' => 'sessions',
    'locking'    => true,
]);
```

## 垃圾回收
<a name="ddbsh-garbage-collection"></a>

使用 ‘expires’ 屬性在 DynamoDB 資料表中設定 TTL 屬性。這會自動對您的工作階段進行廢棄項目收集，您就不需自行手段執行。

或者，DynamoDB 工作階段處理常式支援使用一系列 `Scan`和 `BatchWriteItem`操作收集工作階段垃圾。由於 `Scan` 操作運作方式的本質，和需要找出所有過期的工作階段並加以刪除，垃圾收集程序可能會需要用到許多的佈建傳輸量。

因此，我們不支援自動化的垃圾收集。更理想的做法是將垃圾收集作業排定於離峰時間進行，如此當耗用的傳輸量突增時，就不會干擾到其他的應用程式。例如，您可以設定夜間的 cron 工作，來觸發指令碼，以執行垃圾收集作業。此指令碼需要執行類似下列的動作。

```
$sessionHandler = SessionHandler::fromClient($dynamoDb, [
    'table_name'   => 'sessions',
    'batch_config' => [
        'batch_size' => 25,
        'before' => function ($command) {
            echo "About to delete a batch of expired sessions.\n";
        }
    ]
]);

$sessionHandler->garbageCollect();
```

您也可以使用 `'before'` 中的 `'batch_config'` 選項，來讓垃圾收集程序所執行的 `BatchWriteItem` 操作產生延遲。這將增加垃圾回收完成所需的時間，但可協助您分散 DynamoDB 工作階段處理常式提出的請求，協助您在垃圾回收期間保持接近或低於佈建的輸送容量。

```
$sessionHandler = SessionHandler::fromClient($dynamoDb, [
    'table_name'   => 'sessions',
    'batch_config' => [
        'before' => function ($command) {
            $command['@http']['delay'] = 5000;
        }
    ]
]);

$sessionHandler->garbageCollect();
```

## 最佳實務
<a name="best-practices"></a>

1. 在 AWS 地理位置最接近或與您的應用程式伺服器位於相同區域的 區域中建立工作階段資料表。這可確保應用程式與 DynamoDB 資料庫之間的最低延遲。

1. 請謹慎選擇您的工作階段資料表的佈建輸送容量。請考量至您應用程式的預期傳輸流量，以及工作階段的預期大小。或者，為您的資料表使用「隨需」讀取/寫入容量模式。

1. 透過 AWS 管理主控台或 Amazon CloudWatch 監控消耗的輸送量，並視需要調整輸送量設定，以滿足應用程式的需求。

1. 讓您工作階段的大小保持小型 (最好不到 1 KB)。小型工作階段的效能更為理想，而且需要佈建的輸送容量也較低。

1. 除非您的應用程式要求，否則請勿使用工作階段鎖定。

1. 請透過 cron 任務或其他的排程機制，來進行廢棄項目收集的排程，而不要使用 PHP 內建的工作階段廢棄項目收集觸發，以在離峰時間執行。善用 `'batch_config'` 選項。

## 所需的 IAM 許可
<a name="required-iam-permissions"></a>

若要使用 DynamoDB SessionHhandler，您[設定的登入](guide_credentials.md)資料必須具有許可，才能使用[您在上一個步驟中建立](#create-a-table-for-storing-your-sessions)的 DynamoDB 資料表。下列 IAM 政策包含您需要的最低許可。若要使用此政策，請將資源值取代為您先前建立之資料表的 Amazon Resource Name (ARN)。如需建立和連接 IAM 政策的詳細資訊，請參閱《[IAM 使用者指南》中的管理 IAM 政策](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage.html)。

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "SessionHandler",
            "Action": [
                "dynamodb:GetItem",
                "dynamodb:UpdateItem",
                "dynamodb:DeleteItem",
                "dynamodb:Scan",
                "dynamodb:BatchWriteItem"
            ],
            "Effect": "Allow",
            "Resource": "arn:aws:dynamodb:us-east-1:123456789012:table/table-name"
        }
    ]
}
```

------