Como utilizar o serviço Tabela de Armazenamento do Azure ou o Azure Cosmos DB para Tabela a partir do PHP

APLICA-SE A: Tabela

Aviso

Este projeto está na fase de suporte da comunidade do seu ciclo de vida. Eventualmente, todas as bibliotecas de cliente associadas serão descontinuadas permanentemente. Para obter mais informações sobre a extinção e alternativas à utilização deste projeto, veja Aviso de descontinuação : Bibliotecas de cliente PHP do Armazenamento do Azure.

Dica

O conteúdo neste artigo aplica-se ao Armazenamento de Tabelas do Azure e ao Azure Cosmos DB para Tabela. A API para Tabela é uma oferta premium para armazenamento de tabelas que oferece tabelas otimizadas para débito, distribuição global e índices secundários automáticos.

Este artigo mostra-lhe como criar tabelas, armazenar os seus dados e realizar operações CRUD nos dados. Escolha o serviço Tabela do Azure ou o Azure Cosmos DB para Tabela. Os exemplos são escritos em PHP e utilizam a Biblioteca de Cliente PHP de Tabela de Armazenamento do Azure . Os cenários abrangidos incluem criar e eliminar uma tabela e inserir, eliminar e consultar entidades numa tabela.

Criar conta de serviço do Azure

Pode trabalhar com tabelas com o armazenamento de Tabelas do Azure ou o Azure Cosmos DB. Para saber mais sobre as diferenças entre as ofertas de tabela nestes dois serviços, veja API for Table overview (Descrição geral da API para Tabela). Tem de criar uma conta para o serviço que vai utilizar. As secções seguintes mostram como criar o armazenamento de Tabelas do Azure e a conta do Azure Cosmos DB. No entanto, pode utilizar apenas uma delas.

Table Storage do Azure

A forma mais fácil de criar uma conta de armazenamento do Azure é através do portal do Azure. Para saber mais, veja Criar uma conta de armazenamento.

Também pode criar uma conta de armazenamento do Azure com o Azure PowerShell ou a CLI do Azure.

Se preferir não criar uma conta de armazenamento neste momento, também pode utilizar o Emulador de Armazenamento do Azure para executar e testar o código num ambiente local. Para obter mais informações, veja Utilizar o Emulador de Armazenamento do Azure para desenvolvimento e teste.

Azure Cosmos DB para Tabela

Para obter instruções sobre como criar uma conta do Azure Cosmos DB para Tabela, veja Criar uma conta de base de dados.

Criar uma aplicação PHP

O único requisito para criar uma aplicação PHP para aceder ao serviço Tabela de Armazenamento ou ao Azure Cosmos DB para Tabela é referenciar classes no SDK azure-storage-table para PHP a partir do código. Pode utilizar qualquer ferramenta de desenvolvimento para criar a sua aplicação, incluindo o Notepad.

Neste guia, vai utilizar o Armazenamento de Tabelas do Azure ou o Azure Cosmos DB para funcionalidades de Tabela que podem ser chamadas a partir de uma aplicação PHP. A aplicação pode ser executada localmente ou em código em execução numa função Web, função de trabalho ou site do Azure.

Obter a biblioteca de cliente

  1. Crie um ficheiro chamado composer.json no diretório raiz do seu projeto e adicione o seguinte código ao mesmo:

    {
    "require": {
     "microsoft/azure-storage-table": "*"
    }
    }
    
  2. Transfira o ficheiro composer.phar no seu diretório raiz.

  3. Abra uma linha de comandos e execute o seguinte comando no diretório raiz do seu projeto:

    php composer.phar install
    

    Em alternativa, aceda à Biblioteca de Cliente PHP de Tabela de Armazenamento do Azure no GitHub para clonar o código fonte.

Adicionar as referências necessárias

Para utilizar o serviço Tabela de Armazenamento ou as APIs do Azure Cosmos DB, tem de:

  • Referenciar o ficheiro do carregador automático com a instrução require_once.
  • Referenciar todas as classes que utilizar.

O seguinte exemplo mostra como incluir o ficheiro do carregador automático e referenciar a classe TableRestProxy.

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

Nos exemplos aqui apresentados, a require_once instrução é sempre apresentada, mas apenas as classes necessárias para executar o exemplo são referenciadas.

Adicionar a sua cadeia de ligação

Pode ligar à conta de armazenamento do Azure ou à conta do Azure Cosmos DB para Tabela. Obtenha o cadeia de ligação com base no tipo de conta que está a utilizar.

Adicionar uma ligação do serviço Tabela de Armazenamento

Para instanciar um cliente do serviço Tabela de Armazenamento, primeiro tem de ter uma cadeia de ligação válida. O formato da cadeia de ligação do serviço Tabela de Armazenamento é o seguinte:

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

Adicionar uma ligação do Emulador de Armazenamento

Para aceder ao emulador de armazenamento:

UseDevelopmentStorage = true

Adicionar uma ligação do Azure Cosmos DB

Para instanciar um cliente de Tabelas do Azure Cosmos DB, primeiro tem de ter uma cadeia de ligação válida. O formato da cadeia de ligação do Azure Cosmos DB é:

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

Para criar um cliente do serviço Tabela de Armazenamento ou do Azure Cosmos DB, precisa de utilizar a classe TableRestProxy. Pode:

  • Transmitir a cadeia de ligação diretamente para o mesmo ou
  • Utilize o CloudConfigurationManager (CCM) para verificar várias origens externas do cadeia de ligação:
    • Por predefinição, esta vem com suporte para uma origem de dados externa – variáveis de ambiente.
    • Pode adicionar novas origem de dados ao expandir a classe ConnectionStringSource.

Nos exemplos aqui descritos, a cadeia de ligação é transmitida diretamente.

require_once 'vendor/autoload.php';

use MicrosoftAzure\Storage\Table\TableRestProxy;

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

Criar uma tabela

Um objeto TableRestProxy permite-lhe criar uma tabela com o método createTable. Ao criar uma tabela, pode definir o tempo limite do serviço Tabela. Para obter mais informações sobre o tempo limite do serviço Tabela, veja Setting Timeouts for Table Service Operations (Definir Tempos Limite para Operações de Serviço de Tabela).

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
}

Para obter mais informações sobre as restrições em nomes de tabelas, veja Understanding the Table Service Data Model (Compreender o Modelo de Dados do Serviço Tabela).

Adicionar uma entidade a uma tabela

Para adicionar uma entidade a uma tabela, crie um novo objeto Entidade e transmita-o para TableRestProxy-insertEntity>. Quando cria uma entidade, tem de especificar um PartitionKey e RowKey. Estas entidades são os identificadores exclusivos de uma entidade e são valores que podem ser consultados mais rapidamente do que outras propriedades de entidade. O sistema utiliza a PartitionKey para distribuir automaticamente as entidades da tabela através de vários nós de Armazenamento. As entidades com a mesma PartitionKey são armazenadas no mesmo nó. As operações em várias entidades armazenadas no mesmo nó têm um melhor desempenho do que em entidades armazenadas em diferentes nós. A RowKey é o ID exclusivo de uma entidade numa partição.

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();
}

Para obter informações sobre os tipos e propriedades da Tabela, veja Understanding the Table Service Data Model (Noções Básicas sobre o Modelo de Dados do Serviço Tabela).

A classe TableRestProxy oferece dois métodos alternativos para inserir entidades: insertOrMergeEntity e insertOrReplaceEntity. Para utilizar estes métodos, crie uma nova Entidade e transfira-a como um parâmetro para um dos métodos. Cada método insere a entidade se não existir. Se a entidade já existir, insertOrMergeEntity atualiza os valores de propriedade se as propriedades já existirem e adiciona novas propriedades se não existirem, enquanto insertOrReplaceEntity substitui completamente uma entidade existente. O exemplo seguinte mostra como utilizar insertOrMergeEntity. Se a entidade com PartitionKey "tasksSeattle" e RowKey "1" ainda não existir, essa entidade será inserida. No entanto, se já existir (conforme mostrado no exemplo anterior), a DueDate propriedade é atualizada e a Status propriedade é adicionada. As propriedades Description e Location também são atualizadas, mas com valores que as deixam efetivamente inalteradas. Se estas duas últimas propriedades não aparecerem como mostrado no exemplo, mas existirem na entidade de destino, os respetivos valores existentes permanecerão inalterados.

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 />";
}

Obter uma única entidade

O método TableRestProxy-getEntity> permite-lhe obter uma única entidade ao consultar o respetivo PartitionKey e RowKey. No exemplo aqui, a chave tasksSeattle de partição e a chave 1 de linha são transmitidas para o método getEntity .

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();

Obter todas as entidades numa partição

As consultas de entidades são construídas com filtros. Para obter mais informações, veja Consultar Tabelas e Entidades. Para obter todas as entidades na partição, utilize o filtro PartitionKey eq partition_name. O seguinte exemplo mostra como obter todas as entidades na partição tasksSeattle ao transmitir um filtro para o método queryEntities.

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 />";
}

Obter um subconjunto de entidades numa partição

O mesmo padrão utilizado no exemplo anterior pode ser utilizado para obter qualquer subconjunto de entidades numa partição. O filtro que utiliza determina o subconjunto de entidades que obtém. Para obter mais informações, veja Consultar Tabelas e Entidades. O exemplo seguinte mostra como utilizar um filtro para obter todas as entidades com uma data específica Location e DueDate inferior a uma data especificada.

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 />";
}

Obter um subconjunto de propriedades de entidade

Uma consulta pode obter um subconjunto de propriedades de entidade. Esta técnica, denominada projeção, reduz a largura de banda e pode melhorar o desempenho da consulta, especialmente para entidades grandes. Para especificar uma propriedade a obter, transmita o nome da propriedade para o Query->addSelectField método . Pode chamar este método várias vezes para adicionar mais propriedades. Depois de executar TableRestProxy->queryEntities, as entidades devolvidas terão apenas as propriedades selecionadas. Se quiser devolver um subconjunto de entidades de Tabela, utilize um filtro conforme mostrado nas consultas anteriores.

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 />";
}

Atualizar uma entidade

Pode atualizar uma entidade existente com os métodos Entity-setProperty> e Entity-addProperty> na entidade e, em seguida, chamar TableRestProxy-updateEntity>. O seguinte exemplo obtém uma entidade, modifica uma propriedade, remove outra propriedade e adiciona uma nova propriedade. Pode remover uma propriedade ao definir o respetivo valor como nulo.

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 />";
}

Eliminar uma entidade

Para eliminar uma entidade, transmita o nome da tabela e a entidade PartitionKey e RowKey para o método TableRestProxy-deleteEntity>.

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 />";
}

Para verificações de simultaneidade, pode definir o Etag para que uma entidade seja eliminada através do método DeleteEntityOptions-setEtag> e ao transmitir o objeto DeleteEntityOptions para deleteEntity como um quarto parâmetro.

Operações de tabela de lote

O método TableRestProxy-batch permite-lhe> executar várias operações num único pedido. O padrão aqui envolve adicionar operações ao objeto BatchRequest e, em seguida, transmitir o objeto BatchRequest para o método TableRestProxy-batch>. Para adicionar uma operação a um objeto BatchRequest, pode chamar qualquer um dos seguintes métodos múltiplas vezes:

Description
addInsertEntity Adiciona uma operação insertEntity
addUpdateEntity Adiciona uma operação updateEntity
addMergeEntity Adiciona uma operação mergeEntity
addInsertOrReplaceEntity Adiciona uma operação insertOrReplaceEntity
addInsertOrMergeEntity Adiciona uma operação insertOrMergeEntity
addDeleteEntity Adiciona uma operação deleteEntity

O seguinte exemplo mostra como executar as operações insertEntity e deleteEntity num único pedido.

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 />";
}

Para obter mais informações sobre as operações de Tabela de lote, veja Performing Entity Group Transactions (Efetuar Transações de Grupo de Entidades).

Eliminar uma tabela

Por fim, para eliminar uma tabela, transmita o nome da tabela para o método TableRestProxy-deleteTable>.

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 />";
}