Использование службы таблиц службы хранилища Azure или Azure Cosmos DB для таблиц из PHP

ОБЛАСТЬ ПРИМЕНЕНИЯ: Таблица

Предупреждение

Этот проект находится на этапе поддержки сообщества в его жизненном цикле. В конечном итоге все связанные клиентские библиотеки будут выведены из эксплуатации безвозвратно. Дополнительные сведения о прекращении поддержки и альтернативах использованию этого проекта см. в разделе Уведомление о прекращении поддержки: клиентские библиотеки PHP службы хранилища Azure.

Совет

Содержимое этой статьи относится к хранилищу таблиц Azure и Azure Cosmos DB для таблицы. API для таблиц — это предложение уровня "Премиум" для хранилища таблиц, которое предлагает оптимизированные для пропускной способности таблицы, глобальное распределение и автоматические вторичные индексы.

В этой статье показано, как создавать таблицы, сохранять данные и выполнять операции CRUD с данными. Выберите службу таблиц Azure или Azure Cosmos DB для таблицы. В приведенных здесь примерах, написанных на PHP, используется клиентская библиотека PHP таблиц службы хранилища Azure. Здесь рассматриваются такие сценарии, как создание и удаление таблицы, а также вставка, удаление и запрашивание сущностей в таблице.

Создание учетной записи службы Azure

Вы можете работать с таблицами, используя хранилище таблиц Azure или Azure Cosmos DB. Дополнительные сведения о различиях между предложениями таблиц в этих двух службах см. в обзоре API для таблиц. Необходимо создать учетную запись для службы, которую вы собираетесь использовать. В следующих разделах показано, как создать и хранилище таблиц Azure, и учетную запись Azure Cosmos DB, однако можно использовать что-то одно.

Хранилище таблиц Azure

Самый простой способ создать учетную запись хранения Azure — воспользоваться порталом Azure. Дополнительную информацию см. в статье Об учетных записях хранения Azure.

Учетную запись хранения Azure можно создать также с помощью Azure PowerShell или Azure CLI.

Если вы не хотите сейчас создавать учетную запись хранения, код можно запустить и протестировать в локальной среде с помощью эмулятора хранения Azure. Дополнительные сведения см. в статье Использование Эмулятора службы хранилища Azure для разработки и тестирования.

Azure Cosmos DB for Table

Инструкции по созданию учетной записи Azure Cosmos DB для таблицы см. в статье Создание учетной записи базы данных.

Создание приложения PHP

Единственным требованием для создания приложения PHP для доступа к службе таблиц хранилища или Azure Cosmos DB для таблицы является ссылка на классы в пакете SDK azure-storage-table для PHP из кода. Можно использовать любые средства разработки для создания приложения, включая программу "Блокнот".

В этом руководстве вы используете хранилище таблиц Azure или Azure Cosmos DB для функций таблиц, которые можно вызывать из приложения PHP. Приложение может выполняться локально или в коде, выполняемом в веб-роли, рабочей роли или веб-сайте Azure.

Получение клиентской библиотеки

  1. Создайте файл с именем composer.json в корневой папке проекта и добавьте в него следующий код:

    {
    "require": {
     "microsoft/azure-storage-table": "*"
    }
    }
    
  2. Скачайте файл composer.phar в корневой каталог.

  3. Откройте командную строку и выполните следующую команду в корневом каталоге проекта:

    php composer.phar install
    

    Также можно перейти в клиентскую библиотеку таблиц службы хранилища Azure для PHP на GitHub, чтобы клонировать исходный код.

Добавление обязательных ссылок

Чтобы использовать хранилище таблиц службы хранилища Azure или API-интерфейсы Azure Cosmos DB, необходимо указать следующее:

  • Ссылка на файл автозагрузчика с использованием инструкции require_once и
  • ссылку на все используемые классы.

В следующем примере показано, как включить файл автозагрузчика и добавить ссылку на класс TableRestProxy.

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

В приведенных здесь require_once примерах оператор всегда отображается, но ссылаются только классы, необходимые для выполнения примера.

Добавление строки подключения

Вы можете подключиться либо к учетной записи хранения Azure, либо к учетной записи Azure Cosmos DB для таблицы. Получите строка подключения в зависимости от типа используемой учетной записи.

Добавление подключения к хранилищу таблиц службы хранилища Azure

Для создания экземпляра клиента хранилища таблиц необходимо сначала сформировать правильную строку подключения. Для строки подключения к хранилищу таблиц используется следующий формат:

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

Добавление подключения к эмулятору хранения

Для доступа к эмулятору хранения используйте следующий код:

UseDevelopmentStorage = true

Добавление подключения к Azure Cosmos DB

Для создания экземпляра клиента таблиц Azure Cosmos DB необходимо сначала сформировать правильную строку подключения. Для строки подключения Azure Cosmos DB используется следующий формат:

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

Для создания клиента хранилища таблиц Azure или клиента Azure Cosmos DB необходимо использовать класс TableRestProxy. Вы можете:

  • передать строку подключения напрямую или
  • использовать CloudConfigurationManager (CCM) для проверки нескольких внешних источников на наличие строки подключения:
    • по умолчанию предоставляется поддержка одного внешнего источника — переменных среды;
    • Можно добавить новые источники, расширив класс ConnectionStringSource.

В приведенных здесь примерах строка подключения передается напрямую.

require_once 'vendor/autoload.php';

use MicrosoftAzure\Storage\Table\TableRestProxy;

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

Создание таблицы

Объект TableRestProxy позволяет создать таблицу с помощью метода createTable. При создании таблицы можно задать время ожидания службы таблиц. Дополнительные сведения о времени ожидания службы таблиц см. в разделе Настройка времени ожидания для операций службы таблиц.

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
}

Дополнительные сведения об ограничениях имен таблиц см. в статье Understanding the Table Service Data Model (Основные сведения о модели данных службы таблиц).

Добавление сущности в таблицу

Чтобы добавить сущность в таблицу, создайте объект сущности и передайте его в TableRestProxy->insertEntity. При создании сущности необходимо указать PartitionKey и RowKey. Эти сущности являются уникальными идентификаторами сущности и представляют собой значения, которые можно запрашивать быстрее, чем другие свойства сущности. Система использует PartitionKey, чтобы автоматически распределять сущности таблицы на несколько узлов хранилища. Сущности с одинаковым значением PartitionKey хранятся на одном узле. Операции с несколькими сущностями, хранящимися на одном узле, выполняются лучше, чем с сущностями, хранящимися на разных узлах. RowKey — это уникальный идентификатор сущности в разделе.

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

Дополнительные сведения о типах и свойствах таблиц см. в статье Understanding the Table Service Data Model (Основные сведения о модели данных службы таблиц).

Класс TableRestProxy предлагает два альтернативных способа вставки сущностей: insertOrMergeEntity и insertOrReplaceEntity. Чтобы использовать эти методы, создайте новый объект Entity и передайте его в качестве параметра в любой из этих методов. Каждый метод вставляет сущность, если она не существует. Если сущность уже существует, insertOrMergeEntity обновляет значения свойств, если свойства уже существуют, и добавляет новые свойства, если они не существуют, в то время как insertOrReplaceEntity полностью заменяет существующую сущность. В следующем примере показано, как использовать insertOrMergeEntity. Если сущность с PartitionKey "tasksSeattle" и RowKey "1" еще не существует, эта сущность вставляется. Однако если оно уже существует (как показано в предыдущем примере), DueDate свойство обновляется и Status добавляется. Свойства Description и Location также будут обновлены, однако до таких значений, которые фактически равны предыдущим. Если эти два последних свойства не были добавлены, как показано в примере, но существовали в целевой сущности, их существующие значения останутся неизменными.

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

Извлечение одной сущности

С помощью метода TableRestProxy->getEntity можно получить одну сущность, запросив ее ключи PartitionKey и RowKey. В приведенном здесь примере ключ tasksSeattle секции и ключ 1 строки передаются методу 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();

Получение всех сущностей в разделе

Запросы сущностей создаются с помощью фильтров. Дополнительные сведения см. в разделе Запросы к таблицам и сущностям. Чтобы получить все сущности в секции, используйте фильтр PartitionKey eq partition_name. В следующем примере показано, как получить все сущности в разделе tasksSeattle, передав фильтр в метод 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 />";
}

Получение диапазона сущностей в разделе

Процедуру, аналогичную приведенной в предыдущем примере, можно использовать для получения любого подмножества сущностей в разделе. Используемый фильтр определяет подмножество извлекаемых сущностей. Дополнительные сведения см. в разделе Запросы к таблицам и сущностям. В следующем примере показано, как использовать фильтр для получения всех сущностей с определенной LocationDueDate и меньшей указанной датой.

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

Запрос подмножества свойств сущности

Запрос позволяет получить подмножество свойств сущности. Этот метод, который называется проекцией, снижает потребление полосы пропускания и может повысить производительность запросов, особенно для крупных сущностей. Чтобы указать извлекаемое свойство, передайте имя свойства в Query->addSelectField метод . Этот метод можно вызывать несколько раз для добавления дополнительных свойств. После выполнения TableRestProxy->queryEntitiesвозвращаемые сущности будут иметь только выбранные свойства. Если вы хотите вернуть подмножество сущностей Таблицы, используйте фильтр, как показано в предыдущих запросах.

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

Обновление сущности

Имеющуюся сущность можно обновить, воспользовавшись методами Entity->setProperty и Entity->addProperty, а затем вызвав TableRestProxy->updateEntity. Следующий пример извлекает сущность, изменяет одно свойство, удаляет другое свойство и добавляет новое свойство. Свойство можно удалить, задав для него значение 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 />";
}

Удаление сущности

Чтобы удалить сущность, передайте имя таблицы и ключи сущности PartitionKey и RowKey методу 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 />";
}

При проверке на параллелизм можно задать ETag для удаляемой сущности, воспользовавшись методом DeleteEntityOptions->setEtag и передав объект DeleteEntityOptions в deleteEntity в качестве четвертого параметра.

Пакетные операции с таблицами

С помощью метода TableRestProxy->batch можно выполнять несколько операций в одном запросе. Этот шаблон включает в себя добавление операций в объект BatchRequest и передачу этого объекта методу TableRestProxy->batch. Чтобы добавить операцию в объект BatchRequest , можно вызвать любой из следующих методов несколько раз:

Описание
addInsertEntity Добавляет операцию insertEntity
addUpdateEntity Добавляет операцию updateEntity
addMergeEntity Добавляет операцию mergeEntity
addInsertOrReplaceEntity Добавляет операцию insertOrReplaceEntity
addInsertOrMergeEntity Добавляет операцию insertOrMergeEntity.
addDeleteEntity Добавление операции deleteEntity

В следующем примере показано, как выполнить операции insertEntity и deleteEntity в одном запросе.

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

Дополнительные сведения о пакетной обработке операций с таблицами см. в статье Performing Entity Group Transactions (Выполнение транзакций для группы сущностей).

Удаление таблицы

Наконец, чтобы удалить таблицу, передайте ее имя методу 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 />";
}