How to use Azure Storage Table service or the Azure Cosmos DB for Table from PHP

APPLIES TO: Table

Warning

This project is in the community support stage of it's lifecycle. Eventually, all associated client libraries will be retired permanently. For more information on the retirement and alternatives to using this project, see Retirement notice: Azure Storage PHP client libraries.

Tip

The content in this article applies to Azure Table storage and Azure Cosmos DB for Table. The API for Table is a premium offering for table storage that offers throughput-optimized tables, global distribution, and automatic secondary indexes.

This article shows you how to create tables, store your data, and perform CRUD operations on the data. Choose either the Azure Table service or the Azure Cosmos DB for Table. The samples are written in PHP and use the Azure Storage Table PHP Client Library. The scenarios covered include creating and deleting a table, and inserting, deleting, and querying entities in a table.

Create Azure service account

You can work with tables using the Azure Table storage or the Azure Cosmos DB. To learn more about the differences between table offerings in these two services, see the API for Table overview. You need to create an account for the service you're going to use. The following sections show how to create both Azure Table storage and the Azure Cosmos DB account, however you can just use one of them.

Azure Table Storage

The easiest way to create an Azure storage account is by using the Azure portal. To learn more, see Create a storage account.

You can also create an Azure storage account by using Azure PowerShell or Azure CLI.

If you prefer not to create a storage account at this time, you can also use the Azure Storage Emulator to run and test your code in a local environment. For more information, see Use the Azure Storage Emulator for development and testing.

Azure Cosmos DB for Table

For instructions on creating an Azure Cosmos DB for Table account, see Create a database account.

Create a PHP application

The only requirement to create a PHP application to access the Storage Table service or Azure Cosmos DB for Table is to reference classes in the azure-storage-table SDK for PHP from within your code. You can use any development tools to create your application, including Notepad.

In this guide, you use Azure Table Storage or Azure Cosmos DB for Table features that can be called from within a PHP application. The application can run locally or in code running within an Azure web role, worker role, or website.

Get the client library

  1. Create a file named composer.json in the root of your project and add the following code to it:

    {
    "require": {
     "microsoft/azure-storage-table": "*"
    }
    }
    
  2. Download composer.phar in your root.

  3. Open a command prompt and execute the following command in your project root:

    php composer.phar install
    

    Alternatively, go to the Azure Storage Table PHP Client Library on GitHub to clone the source code.

Add required references

To use the Storage Table service or Azure Cosmos DB APIs, you must:

  • Reference the autoloader file using the require_once statement, and
  • Reference any classes you use.

The following example shows how to include the autoloader file and reference the TableRestProxy class.

require_once 'vendor/autoload.php';
use MicrosoftAzure\Storage\Table\TableRestProxy;

In the examples here, the require_once statement is always shown, but only the classes necessary for the example to execute are referenced.

Add your connection string

You can either connect to the Azure storage account or the Azure Cosmos DB for Table account. Get the connection string based on the type of account you're using.

Add a Storage Table service connection

To instantiate a Storage Table service client, you must first have a valid connection string. The format for the Storage Table service connection string is:

$connectionString = "DefaultEndpointsProtocol=[http|https];AccountName=[yourAccount];AccountKey=[yourKey]"

Add a Storage Emulator connection

To access the emulator storage:

UseDevelopmentStorage = true

Add an Azure Cosmos DB connection

To instantiate an Azure Cosmos DB Table client, you must first have a valid connection string. The format for the Azure Cosmos DB connection string is:

$connectionString = "DefaultEndpointsProtocol=[https];AccountName=[myaccount];AccountKey=[myaccountkey];TableEndpoint=[https://myendpoint/]";

To create an Azure Table service client or Azure Cosmos DB client, you need to use the TableRestProxy class. You can:

  • Pass the connection string directly to it or
  • Use the CloudConfigurationManager (CCM) to check multiple external sources for the connection string:
    • By default, it comes with support for one external source - environmental variables.
    • You can add new sources by extending the ConnectionStringSource class.

For the examples outlined here, the connection string is passed directly.

require_once 'vendor/autoload.php';

use MicrosoftAzure\Storage\Table\TableRestProxy;

$tableClient = TableRestProxy::createTableService($connectionString);

Create a table

A TableRestProxy object lets you create a table with the createTable method. When creating a table, you can set the Table service timeout. For more information about the Table service timeout, see Setting Timeouts for Table Service Operations.

require_once 'vendor\autoload.php';

use MicrosoftAzure\Storage\Table\TableRestProxy;
use MicrosoftAzure\Storage\Common\Exceptions\ServiceException;

// Create Table REST proxy.
$tableClient = TableRestProxy::createTableService($connectionString);

try    {
    // Create table.
    $tableClient->createTable("mytable");
}
catch(ServiceException $e){
    $code = $e->getCode();
    $error_message = $e->getMessage();
    // Handle exception based on error codes and messages.
    // Error codes and messages can be found here:
    // https://learn.microsoft.com/rest/api/storageservices/Table-Service-Error-Codes
}

For information about restrictions on table names, see Understanding the Table Service Data Model.

Add an entity to a table

To add an entity to a table, create a new Entity object and pass it to TableRestProxy->insertEntity. When you create an entity, you must specify a PartitionKey and RowKey. These entities are the unique identifiers for an entity and are values that can be queried faster than other entity properties. The system uses PartitionKey to automatically distribute the table's entities over many Storage nodes. Entities with the same PartitionKey are stored on the same node. Operations on multiple entities stored on the same node perform better than on entities stored across different nodes. The RowKey is the unique ID of an entity within a partition.

require_once 'vendor/autoload.php';

use MicrosoftAzure\Storage\Table\TableRestProxy;
use MicrosoftAzure\Storage\Common\Exceptions\ServiceException;
use MicrosoftAzure\Storage\Table\Models\Entity;
use MicrosoftAzure\Storage\Table\Models\EdmType;

// Create table REST proxy.
$tableClient = TableRestProxy::createTableService($connectionString);

$entity = new Entity();
$entity->setPartitionKey("tasksSeattle");
$entity->setRowKey("1");
$entity->addProperty("Description", null, "Take out the trash.");
$entity->addProperty("DueDate",
                        EdmType::DATETIME,
                        new DateTime("2012-11-05T08:15:00-08:00"));
$entity->addProperty("Location", EdmType::STRING, "Home");

try{
    $tableClient->insertEntity("mytable", $entity);
}
catch(ServiceException $e){
    // Handle exception based on error codes and messages.
    // Error codes and messages are here:
    // https://learn.microsoft.com/rest/api/storageservices/Table-Service-Error-Codes
    $code = $e->getCode();
    $error_message = $e->getMessage();
}

For information about Table properties and types, see Understanding the Table Service Data Model.

The TableRestProxy class offers two alternative methods for inserting entities: insertOrMergeEntity and insertOrReplaceEntity. To use these methods, create a new Entity and pass it as a parameter to either method. Each method inserts the entity if it doesn't exist. If the entity already exists, insertOrMergeEntity updates property values if the properties already exist and adds new properties if they don't exist, while insertOrReplaceEntity completely replaces an existing entity. The following example shows how to use insertOrMergeEntity. If the entity with PartitionKey "tasksSeattle" and RowKey "1" doesn't already exist, that entity is then inserted. However, if it already exists (as shown in the previous example), the DueDate property is updated, and the Status property is added. The Description and Location properties are also updated, but with values that effectively leave them unchanged. If these latter two properties weren't added as shown in the example, but existed on the target entity, their existing values would remain unchanged.

require_once 'vendor/autoload.php';

use MicrosoftAzure\Storage\Table\TableRestProxy;
use MicrosoftAzure\Storage\Common\Exceptions\ServiceException;
use MicrosoftAzure\Storage\Table\Models\Entity;
use MicrosoftAzure\Storage\Table\Models\EdmType;

// Create table REST proxy.
$tableClient = TableRestProxy::createTableService($connectionString);

//Create new entity.
$entity = new Entity();

// PartitionKey and RowKey are required.
$entity->setPartitionKey("tasksSeattle");
$entity->setRowKey("1");

// If entity exists, existing properties are updated with new values and
// new properties are added. Missing properties are unchanged.
$entity->addProperty("Description", null, "Take out the trash.");
$entity->addProperty("DueDate", EdmType::DATETIME, new DateTime()); // Modified the DueDate field.
$entity->addProperty("Location", EdmType::STRING, "Home");
$entity->addProperty("Status", EdmType::STRING, "Complete"); // Added Status field.

try    {
    // Calling insertOrReplaceEntity, instead of insertOrMergeEntity as shown,
    // would simply replace the entity with PartitionKey "tasksSeattle" and RowKey "1".
    $tableClient->insertOrMergeEntity("mytable", $entity);
}
catch(ServiceException $e){
    // Handle exception based on error codes and messages.
    // Error codes and messages are here:
    // https://learn.microsoft.com/rest/api/storageservices/Table-Service-Error-Codes
    $code = $e->getCode();
    $error_message = $e->getMessage();
    echo $code.": ".$error_message."<br />";
}

Retrieve a single entity

The TableRestProxy->getEntity method allows you to retrieve a single entity by querying for its PartitionKey and RowKey. In the example here, the partition key tasksSeattle and row key 1 are passed to the getEntity method.

require_once 'vendor/autoload.php';

use MicrosoftAzure\Storage\Table\TableRestProxy;
use MicrosoftAzure\Storage\Common\Exceptions\ServiceException;

// Create table REST proxy.
$tableClient = TableRestProxy::createTableService($connectionString);

try    {
    $result = $tableClient->getEntity("mytable", "tasksSeattle", 1);
}
catch(ServiceException $e){
    // Handle exception based on error codes and messages.
    // Error codes and messages are here:
    // https://learn.microsoft.com/rest/api/storageservices/Table-Service-Error-Codes
    $code = $e->getCode();
    $error_message = $e->getMessage();
    echo $code.": ".$error_message."<br />";
}

$entity = $result->getEntity();

echo $entity->getPartitionKey().":".$entity->getRowKey();

Retrieve all entities in a partition

Entity queries are constructed using filters. For more information, see Querying Tables and Entities. To retrieve all entities in partition, use the filter PartitionKey eq partition_name. The following example shows how to retrieve all entities in the tasksSeattle partition by passing a filter to the queryEntities method.

require_once 'vendor/autoload.php';

use MicrosoftAzure\Storage\Table\TableRestProxy;
use MicrosoftAzure\Storage\Common\Exceptions\ServiceException;

// Create table REST proxy.
$tableClient = TableRestProxy::createTableService($connectionString);

$filter = "PartitionKey eq 'tasksSeattle'";

try    {
    $result = $tableClient->queryEntities("mytable", $filter);
}
catch(ServiceException $e){
    // Handle exception based on error codes and messages.
    // Error codes and messages are here:
    // https://learn.microsoft.com/rest/api/storageservices/Table-Service-Error-Codes
    $code = $e->getCode();
    $error_message = $e->getMessage();
    echo $code.": ".$error_message."<br />";
}

$entities = $result->getEntities();

foreach($entities as $entity){
    echo $entity->getPartitionKey().":".$entity->getRowKey()."<br />";
}

Retrieve a subset of entities in a partition

The same pattern used in the previous example can be used to retrieve any subset of entities in a partition. The filter you use determines the subset of entities you retrieve. For more information, see Querying Tables and Entities. The following example shows how to use a filter to retrieve all entities with a specific Location and a DueDate less than a specified date.

require_once 'vendor/autoload.php';

use MicrosoftAzure\Storage\Table\TableRestProxy;
use MicrosoftAzure\Storage\Common\Exceptions\ServiceException;

// Create table REST proxy.
$tableClient = TableRestProxy::createTableService($connectionString);

$filter = "Location eq 'Office' and DueDate lt '2012-11-5'";

try    {
    $result = $tableClient->queryEntities("mytable", $filter);
}
catch(ServiceException $e){
    // Handle exception based on error codes and messages.
    // Error codes and messages are here:
    // https://learn.microsoft.com/rest/api/storageservices/Table-Service-Error-Codes
    $code = $e->getCode();
    $error_message = $e->getMessage();
    echo $code.": ".$error_message."<br />";
}

$entities = $result->getEntities();

foreach($entities as $entity){
    echo $entity->getPartitionKey().":".$entity->getRowKey()."<br />";
}

Retrieve a subset of entity properties

A query can retrieve a subset of entity properties. This technique, called projection, reduces bandwidth and can improve query performance, especially for large entities. To specify a property to retrieve, pass the name of the property to the Query->addSelectField method. You can call this method multiple times to add more properties. After you execute TableRestProxy->queryEntities, the returned entities will only have the selected properties. If you want to return a subset of Table entities, use a filter as shown in the previous queries.

require_once 'vendor/autoload.php';

use MicrosoftAzure\Storage\Table\TableRestProxy;
use MicrosoftAzure\Storage\Common\Exceptions\ServiceException;
use MicrosoftAzure\Storage\Table\Models\QueryEntitiesOptions;

// Create table REST proxy.
$tableClient = TableRestProxy::createTableService($connectionString);

$options = new QueryEntitiesOptions();
$options->addSelectField("Description");

try    {
    $result = $tableClient->queryEntities("mytable", $options);
}
catch(ServiceException $e){
    // Handle exception based on error codes and messages.
    // Error codes and messages are here:
    // https://learn.microsoft.com/rest/api/storageservices/Table-Service-Error-Codes
    $code = $e->getCode();
    $error_message = $e->getMessage();
    echo $code.": ".$error_message."<br />";
}

// All entities in the table are returned, regardless of whether
// they have the Description field.
// To limit the results returned, use a filter.
$entities = $result->getEntities();

foreach($entities as $entity){
    $description = $entity->getProperty("Description")->getValue();
    echo $description."<br />";
}

Update an entity

You can update an existing entity by using the Entity->setProperty and Entity->addProperty methods on the entity, and then calling TableRestProxy->updateEntity. The following example retrieves an entity, modifies one property, removes another property, and adds a new property. You can remove a property by setting its value to null.

require_once 'vendor/autoload.php';

use MicrosoftAzure\Storage\Table\TableRestProxy;
use MicrosoftAzure\Storage\Common\Exceptions\ServiceException;
use MicrosoftAzure\Storage\Table\Models\Entity;
use MicrosoftAzure\Storage\Table\Models\EdmType;

// Create table REST proxy.
$tableClient = TableRestProxy::createTableService($connectionString);

$result = $tableClient->getEntity("mytable", "tasksSeattle", 1);

$entity = $result->getEntity();
$entity->setPropertyValue("DueDate", new DateTime()); //Modified DueDate.
$entity->setPropertyValue("Location", null); //Removed Location.
$entity->addProperty("Status", EdmType::STRING, "In progress"); //Added Status.

try    {
    $tableClient->updateEntity("mytable", $entity);
}
catch(ServiceException $e){
    // Handle exception based on error codes and messages.
    // Error codes and messages are here:
    // https://learn.microsoft.com/rest/api/storageservices/Table-Service-Error-Codes
    $code = $e->getCode();
    $error_message = $e->getMessage();
    echo $code.": ".$error_message."<br />";
}

Delete an entity

To delete an entity, pass the table name, and the entity's PartitionKey and RowKey to the TableRestProxy->deleteEntity method.

require_once 'vendor/autoload.php';

use MicrosoftAzure\Storage\Table\TableRestProxy;
use MicrosoftAzure\Storage\Common\Exceptions\ServiceException;

// Create table REST proxy.
$tableClient = TableRestProxy::createTableService($connectionString);

try    {
    // Delete entity.
    $tableClient->deleteEntity("mytable", "tasksSeattle", "2");
}
catch(ServiceException $e){
    // Handle exception based on error codes and messages.
    // Error codes and messages are here:
    // https://learn.microsoft.com/rest/api/storageservices/Table-Service-Error-Codes
    $code = $e->getCode();
    $error_message = $e->getMessage();
    echo $code.": ".$error_message."<br />";
}

For concurrency checks, you can set the Etag for an entity to be deleted by using the DeleteEntityOptions->setEtag method and passing the DeleteEntityOptions object to deleteEntity as a fourth parameter.

Batch table operations

The TableRestProxy->batch method allows you to execute multiple operations in a single request. The pattern here involves adding operations to BatchRequest object and then passing the BatchRequest object to the TableRestProxy->batch method. To add an operation to a BatchRequest object, you can call any of the following methods multiple times:

Description
addInsertEntity Adds an insertEntity operation
addUpdateEntity Adds an updateEntity operation
addMergeEntity Adds a mergeEntity operation
addInsertOrReplaceEntity Adds an insertOrReplaceEntity operation
addInsertOrMergeEntity Adds an insertOrMergeEntity operation
addDeleteEntity Adds a deleteEntity operation

The following example shows how to execute insertEntity and deleteEntity operations in a single request.

require_once 'vendor/autoload.php';

use MicrosoftAzure\Storage\Table\TableRestProxy;
use MicrosoftAzure\Storage\Common\Exceptions\ServiceException;
use MicrosoftAzure\Storage\Table\Models\Entity;
use MicrosoftAzure\Storage\Table\Models\EdmType;
use MicrosoftAzure\Storage\Table\Models\BatchOperations;

// Configure a connection string for Storage Table service.
$connectionString = "DefaultEndpointsProtocol=[http|https];AccountName=[yourAccount];AccountKey=[yourKey]"

// Create table REST proxy.
$tableClient = TableRestProxy::createTableService($connectionString);

// Create list of batch operation.
$operations = new BatchOperations();

$entity1 = new Entity();
$entity1->setPartitionKey("tasksSeattle");
$entity1->setRowKey("2");
$entity1->addProperty("Description", null, "Clean roof gutters.");
$entity1->addProperty("DueDate",
                        EdmType::DATETIME,
                        new DateTime("2012-11-05T08:15:00-08:00"));
$entity1->addProperty("Location", EdmType::STRING, "Home");

// Add operation to list of batch operations.
$operations->addInsertEntity("mytable", $entity1);

// Add operation to list of batch operations.
$operations->addDeleteEntity("mytable", "tasksSeattle", "1");

try    {
    $tableClient->batch($operations);
}
catch(ServiceException $e){
    // Handle exception based on error codes and messages.
    // Error codes and messages are here:
    // https://learn.microsoft.com/rest/api/storageservices/Table-Service-Error-Codes
    $code = $e->getCode();
    $error_message = $e->getMessage();
    echo $code.": ".$error_message."<br />";
}

For more information about batching Table operations, see Performing Entity Group Transactions.

Delete a table

Finally, to delete a table, pass the table name to the TableRestProxy->deleteTable method.

require_once 'vendor/autoload.php';

use MicrosoftAzure\Storage\Table\TableRestProxy;
use MicrosoftAzure\Storage\Common\Exceptions\ServiceException;

// Create table REST proxy.
$tableClient = TableRestProxy::createTableService($connectionString);

try    {
    // Delete table.
    $tableClient->deleteTable("mytable");
}
catch(ServiceException $e){
    // Handle exception based on error codes and messages.
    // Error codes and messages are here:
    // https://learn.microsoft.com/rest/api/storageservices/Table-Service-Error-Codes
    $code = $e->getCode();
    $error_message = $e->getMessage();
    echo $code.": ".$error_message."<br />";
}