StandardSessionConnection.php 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. <?php
  2. namespace Aws\DynamoDb;
  3. use Aws\DynamoDb\Exception\DynamoDbException;
  4. /**
  5. * The standard connection performs the read and write operations to DynamoDB.
  6. */
  7. class StandardSessionConnection implements SessionConnectionInterface
  8. {
  9. use SessionConnectionConfigTrait;
  10. /** @var DynamoDbClient The DynamoDB client */
  11. protected $client;
  12. /**
  13. * @param DynamoDbClient $client DynamoDB client
  14. * @param array $config Session handler config
  15. */
  16. public function __construct(DynamoDbClient $client, array $config = [])
  17. {
  18. $this->client = $client;
  19. $this->initConfig($config);
  20. }
  21. public function read($id)
  22. {
  23. $item = [];
  24. try {
  25. // Execute a GetItem command to retrieve the item.
  26. $result = $this->client->getItem([
  27. 'TableName' => $this->getTableName(),
  28. 'Key' => $this->formatKey($id),
  29. 'ConsistentRead' => $this->isConsistentRead(),
  30. ]);
  31. // Get the item values
  32. $result = isset($result['Item']) ? $result['Item'] : [];
  33. foreach ($result as $key => $value) {
  34. $item[$key] = current($value);
  35. }
  36. } catch (DynamoDbException $e) {
  37. // Could not retrieve item, so return nothing.
  38. }
  39. return $item;
  40. }
  41. public function write($id, $data, $isChanged)
  42. {
  43. // Prepare the attributes
  44. $expires = time() + $this->getSessionLifetime();
  45. $attributes = [
  46. $this->getSessionLifetimeAttribute() => ['Value' => ['N' => (string) $expires]],
  47. 'lock' => ['Action' => 'DELETE'],
  48. ];
  49. if ($isChanged) {
  50. if ($data != '') {
  51. $type = $this->getDataAttributeType();
  52. if ($type == 'binary') {
  53. $attributes[$this->getDataAttribute()] = ['Value' => ['B' => $data]];
  54. } else {
  55. $attributes[$this->getDataAttribute()] = ['Value' => ['S' => $data]];
  56. }
  57. } else {
  58. $attributes[$this->getDataAttribute()] = ['Action' => 'DELETE'];
  59. }
  60. }
  61. // Perform the UpdateItem command
  62. try {
  63. return (bool) $this->client->updateItem([
  64. 'TableName' => $this->getTableName(),
  65. 'Key' => $this->formatKey($id),
  66. 'AttributeUpdates' => $attributes,
  67. ]);
  68. } catch (DynamoDbException $e) {
  69. return $this->triggerError("Error writing session $id: {$e->getMessage()}");
  70. }
  71. }
  72. public function delete($id)
  73. {
  74. try {
  75. return (bool) $this->client->deleteItem([
  76. 'TableName' => $this->getTableName(),
  77. 'Key' => $this->formatKey($id),
  78. ]);
  79. } catch (DynamoDbException $e) {
  80. return $this->triggerError("Error deleting session $id: {$e->getMessage()}");
  81. }
  82. }
  83. public function deleteExpired()
  84. {
  85. // Create a Scan iterator for finding expired session items
  86. $scan = $this->client->getPaginator('Scan', [
  87. 'TableName' => $this->getTableName(),
  88. 'AttributesToGet' => [$this->getHashKey()],
  89. 'ScanFilter' => [
  90. $this->getSessionLifetimeAttribute() => [
  91. 'ComparisonOperator' => 'LT',
  92. 'AttributeValueList' => [['N' => (string) time()]],
  93. ],
  94. 'lock' => [
  95. 'ComparisonOperator' => 'NULL',
  96. ]
  97. ],
  98. ]);
  99. // Create a WriteRequestBatch for deleting the expired items
  100. $batch = new WriteRequestBatch($this->client, $this->getBatchConfig());
  101. // Perform Scan and BatchWriteItem (delete) operations as needed
  102. foreach ($scan->search('Items') as $item) {
  103. $batch->delete(
  104. [$this->getHashKey() => $item[$this->getHashKey()]],
  105. $this->getTableName()
  106. );
  107. }
  108. // Delete any remaining items that were not auto-flushed
  109. $batch->flush();
  110. }
  111. /**
  112. * @param string $key
  113. *
  114. * @return array
  115. */
  116. protected function formatKey($key)
  117. {
  118. return [$this->getHashKey() => ['S' => $key]];
  119. }
  120. /**
  121. * @param string $error
  122. *
  123. * @return bool
  124. */
  125. protected function triggerError($error)
  126. {
  127. trigger_error($error, E_USER_WARNING);
  128. return false;
  129. }
  130. }