Categories
AWS

How to get items from DynamoDB table using PHP

Last updated on August 3rd, 2022 at 08:24 am

In this tutorial we are going to talk more on connecting to Amazon DynamoDB using PHP and getting data from the table.

What is DynamoDB?

Amazon DynamoDB is a fully managed NoSQL database service. It provide low latency and can be configured with applications for best performance and seamless scalability. Data is stored in Key Value format. It has two read and write capacity modes for processsing data from the tables

1] On-Demand
2] Provisioned

More details can be found in this public documentation 

Steps to install AWS SDK for PHP

Inorder for you to connect to DynamoDB we need to first install AWS SDK. There are mainly 3 different ways you can install AWS SDK for PHP

  •     Installing using Composer (recommended)
  •     Installing using the PHP archive (.phar)
  •     Installing using the .zip archive

More details https://docs.aws.amazon.com/aws-sdk-php/v2/guide/installation.html

I am using .zip archive option here. If you wish to proceed with other ways of installation refer the documentation above.

1] Go to this github repp maintained by AWS
https://github.com/aws/aws-sdk-php/releases

2] Download the aws.zip file, During the time of writing this tutorial version 3.231.0 was the latest available. I am downloading that. Make sure you download the latest version aws.zip file available unless you have very specific requirements to use a particular version.

https://github.com/aws/aws-sdk-php/releases/download/3.231.0/aws.zip

3] Extract the aws.zip file to the location where your PHP file (to connect to dynamodb) is deployed

4] This is a sample list of files/directories inside aws.zip(top-level)

-rw-r--r--  unx    12035 tx defN 22-Jun-28 18:16 README.md
-rw-r--r--  unx     9202 tx defN 22-Jun-28 18:16 LICENSE
-rw-r--r--  unx      638 tx defN 22-Jun-28 18:16 NOTICE
-rw-r--r--  unx   987280 tx defN 22-Jun-28 18:16 CHANGELOG.md
drwxr-xr-x  unx        0 bx stor 22-Jun-28 18:16 Aws/
drwxr-xr-x  unx        0 bx stor 22-Jun-28 18:16 JmesPath/
drwxr-xr-x  unx        0 bx stor 22-Jun-28 18:16 GuzzleHttp/
drwxr-xr-x  unx        0 bx stor 22-Jun-28 18:16 Psr/
drwxr-xr-x  unx        0 bx stor 22-Jun-28 18:16 Symfony/
-rw-r--r--  unx   203856 tx defN 22-Jun-28 18:16 aws-autoloader.php

Connect to DynamoDb

In order for you to connect to the AWS DynamoDB endpoint you need to first load the aws-autoloader.php and then use the  DynamoDBClient file to configure credentials.

Make sure that the require statement has the correct path to load aws-autoloader.php. This file comes along with the aws.zip we extracted during the installation of PHP SDK

Method 1

We can provide region / profile information along with the version using DynamoDbClient::factory() method as shown below

<?php
require 'aws-autoloader.php';
use Aws\DynamoDb\DynamoDbClient;
$client = DynamoDbClient::factory(array(
    'profile' => 'default',
    'region'  => 'us-east-1',
    'version' => 'latest'
));
?>

The profile option will identify your ~/.aws/credentials file and read the default profile details from there.

Method 2

If you don’t have a AWS CLI profile locally configured on your server and want to pass the access key and secret key directly in the code use this .

It is not recommended to save your access_key and secret_key in the code.

$client = DynamoDbClient::factory(array(
    'key'    => '[aws access key]',
    'secret' => '[aws secret key]',
    'region' => '[aws region]',
'version' => 'latest'
));

If you opt to follow Method 2 at least make sure that you get the access and secret key from an environment variable within the server and refrain from adding any credentials to the PHP code. I personally recommend Method 1 🙂

Get Attribute Name and Type

Using describeTable we can extract easily ItemCount , Tablesize and ofcourse AttributeName along with Type.

All you have to do here is add your table name, in my case it is mytable and execute the describeTable API call as shown

$tableName='mytable';
$result = $client->describeTable(array(
    'TableName' => $tableName
));

As you can see $result variable has all the details of the describe call. It returns information about the table, current status of the table, primary key schema, and any indexes on the table. Take a look at this documentation to see exact same details . It also clearly explains the attributes returned.

Sample Output

{
    "Table": {
        "AttributeDefinitions": [
            {
                "AttributeName": "id",
                "AttributeType": "S"
            },
            {
                "AttributeName": "name",
                "AttributeType": "S"
            }
        ],
        "TableName": "mytable",
        "KeySchema": [
            {
                "AttributeName": "id",
                "KeyType": "HASH"
            },
            {
                "AttributeName": "name",
                "KeyType": "RANGE"
            }
        ],
        "TableStatus": "ACTIVE",
        "CreationDateTime": "2022-06-28T15:37:20+00:00",
        "ProvisionedThroughput": {
            "LastDecreaseDateTime": "2022-06-28T15:51:01+00:00",
            "NumberOfDecreasesToday": 0,
            "ReadCapacityUnits": 1,
            "WriteCapacityUnits": 1
        },
        "TableSizeBytes": 320,
        "ItemCount": 5,
        "TableArn": "arn:aws:dynamodb:us-east-1:xxxx:table\/mytable",
        "TableId": "d0c18c33-4a34-a2f1-edc3dd493eff",
        "StreamSpecification": {
            "StreamEnabled": true,
            "StreamViewType": "NEW_AND_OLD_IMAGES"
        },
        "LatestStreamLabel": "2022-06-28T15:38:37.181",
        "LatestStreamArn": "arn:aws:dynamodb:us-east-1:xxx:table\/mytable\/stream\/2022-06-28T15:38:37.181",
        "GlobalTableVersion": "2019.11.21",
        "Replicas": [
            {
                "RegionName": "eu-west-1",
                "ReplicaStatus": "ACTIVE"
            }
        ]
    },
    "@metadata": {
        "statusCode": 200,
        "effectiveUri": "https:\/\/dynamodb.us-east-1.amazonaws.com",
        "headers": {
            "server": "Server",
            "date": "Mon, 11 Jul 2022 16:03:25 GMT",
            "content-type": "application\/x-amz-json-1.0",
            "content-length": "951",
            "connection": "close",
            "x-amzn-requestid": "25DJHPNABH4AAJG",
            "x-amz-crc32": "32503xx0"
        },
        "transferStats": {
            "http": [
                []
            ]
        }
    }
}

I have two attributes in mytable, id and name. I also have a replica in EU-WEST-1 and that is the reason you are seeing Replicas block within my table properties above.

Let us now look in to extracting some of those values from the above table properties dump.

For getting the total items , table size in bytes and the Attributes defined with name and type

echo "\nTotal Items ".$result['Table']['ItemCount'] . "\n";
echo "Table Size In Bytes ".$result['Table']['TableSizeBytes'] . "\n";
foreach ($result['Table']['AttributeDefinitions'] as $def)
{
echo "Name: ".$def['AttributeName']." Type: ".$def['AttributeType']."\n";
}

Note: The ItemCount value is only updated every six hours. More details on table description along with the properties of each attribute is described in this document.

Sample Output

Total Items 5
Table Size In Bytes 320
Name: id Type: S
Name: name Type: S
=======

Get all items in the table

In order to get all the items in a table we have to use getIterator. We will basically scan the table and then use foreach statement to loop through each item within the table.

$iterator = $client->getIterator('Scan', array(
    'TableName' => $tableName,
      'Select' => 'ALL_ATTRIBUTES')
 );
// Each item will contain the attributes we added
foreach ($iterator as $item) {
    // Grab the id value
    echo "ID ".$item['id']['S'] . "\n";
    // Grab the name value
    echo "Name ".$item['name']['S'] . "\n";
    echo "----\n";
}

Sample Output

ID 22
Name Accessories
----
ID 12
Name Gadgets
----
ID 51
Name Food
----
ID 41
Name AutoMotive
----
ID 38
Name Fuel
----

Complete PHP Code

Until now we had a break down on each piece of the code, for your reference I am sharing the complete code.

<?php
require 'aws-autoloader.php';
use Aws\DynamoDb\DynamoDbClient;
$client = DynamoDbClient::factory(array(
    'profile' => 'default',
    'region'  => 'us-east-1',
    'version' => 'latest'
));

$tableName='mytable';
$result = $client->describeTable(array(
    'TableName' => $tableName
));
echo "======\n";
echo $result;
echo "\nTotal Items ".$result['Table']['ItemCount'] . "\n";
echo "Table Size In Bytes ".$result['Table']['TableSizeBytes'] . "\n";
foreach ($result['Table']['AttributeDefinitions'] as $def)
{
echo "Name: ".$def['AttributeName']." Type: ".$def['AttributeType']."\n";
}
echo "=======\n";
echo "\n";
$iterator = $client->getIterator('Scan', array(
    'TableName' => $tableName,
      'Select' => 'ALL_ATTRIBUTES')
 );

// Each item will contain the attributes we added
foreach ($iterator as $item) {
    echo "ID ".$item['id']['S'] . "\n";
    echo "Name ".$item['name']['S'] . "\n";
    echo "----\n";
}

?>
Click to rate this tutorial!
[Total: 1 Average: 4]

Leave a Reply

Your email address will not be published. Required fields are marked *