如何使用 PHP 的 Azure 儲存體資料表服務或 Azure Cosmos DB for Table

適用於: 數據表

警告

此項目位於其生命週期的 社群支持 階段。 最後,所有相關聯的用戶端連結庫都將永久淘汰。 如需停用和使用此專案替代專案的詳細資訊,請參閱 淘汰注意事項:Azure 記憶體 PHP 用戶端連結庫

提示

本文中的內容適用於 Azure 資料表記憶體和適用於資料表的 Azure Cosmos DB。 數據表的 API 是數據表記憶體的進階供應專案,可提供輸送量優化的數據表、全域散發和自動次要索引。

此文章說明如何建立資料表、儲存您的資料,以及對資料執行 CRUD 作業。 選擇 Azure 資料表服務或 Azure Cosmos DB for Table。 這些範例是以 PHP 撰寫,並且使用 Azure 儲存體資料表 PHP 用戶端程式庫。 所涵蓋的案例包括建立和刪除資料表以及在資料表中插入、刪除及查詢實體

建立 Azure 服務帳戶

您可以使用 Azure 表格儲存體或 Azure Cosmos DB 來搭配使用表格。 若要深入瞭解這兩個服務中的數據表供應專案之間的差異,請參閱 數據表的 API 概觀。 您必須為要使用的服務建立帳戶。 下列各節說明如何建立 Azure 資料表儲存體和 Azure Cosmos DB 帳戶,不過您可以只使用其中一個。

Azure 資料表儲存體

建立 Azure 儲存體帳戶最簡單的方法,就是使用 Azure 入口網站。 若要深入了解,請參閱 建立儲存體帳戶

您也可以使用 Azure PowerShellAzure CLI 來建立 Azure 儲存體帳戶。

如果您不想在此時建立儲存體帳戶,也可以使用 Azure 儲存體模擬器在本機環境中執行並測試您的程式碼。 如需詳細資訊,請參閱使用 Azure 儲存體模擬器進行開發和測試

Azure Cosmos DB for Table

如需建立 Azure Cosmos DB for Table 帳戶的相關指示,請參閱建立資料庫帳戶

建立 PHP 應用程式

建立 PHP 應用程式以存取儲存體資料表服務或 Azure Cosmos DB for Table 的唯一要求,就是從您的程式碼中參考適用於 PHP 的 azure-storage-table SDK 類別。 您可以使用任何開發工具來建立應用程式 (包括 [記事本])。

在本指南中,您會使用可從 PHP 應用程式內呼叫的 Azure 數據表記憶體或 Azure Cosmos DB for Table 功能。 應用程式可以在本機或在 Azure Web 角色、背景工作角色或網站內執行的程式代碼中執行。

取得用戶端程式庫

  1. 在專案的根目錄中建立名為 composer.json 的檔案,並新增下列程式碼:

    {
    "require": {
     "microsoft/azure-storage-table": "*"
    }
    }
    
  2. composer.phar 下載到根目錄中。

  3. 開啟命令提示字元,在專案根目錄中執行下列命令:

    php composer.phar install
    

    或者,移至 GitHub 上的 Azure 儲存體資料表 PHP 用戶端程式庫來複製原始程式碼。

新增必要的參考

若要使用儲存體表格服務或 Azure Cosmos DB API,您必須:

  • 參考使用 require_once 陳述式的自動載入器檔案,以及
  • 參考您使用的任何類別。

下列範例會示範如何納入自動換片器檔案及參考 TableRestProxy 類別。

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

在此範例中 require_once ,一律會顯示 語句,但只會參考範例執行所需的類別。

新增連接字串

您可以連線到 Azure 儲存體帳戶或 Azure Cosmos DB for Table 帳戶。 根據您所使用的帳戶類型取得 連接字串。

新增儲存體表格服務連線

若要具現化儲存體表格服務用戶端,您必須先具備一個有效的連接字串。 儲存體表格服務的連接字串格式為:

$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
}

如需有關資料表名稱限制的資訊,請參閱了解表格服務資料模型

將實體新增至資料表

若要將實體新增至資料表,請建立一個新的 Entity 物件,然後將該物件傳遞給 TableRestProxy->insertEntity。 您建立實體時,必須指定 PartitionKeyRowKey。 這些實體是實體的唯一標識碼,而且是可比其他實體屬性更快速查詢的值。 系統使用 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();
}

如需有關資料表屬性和類型的資訊,請參閱了解表格服務資料模型

TableRestProxy 類別提供兩種插入實體的替代方法:insertOrMergeEntityinsertOrReplaceEntity。 若要使用這些方法,請建立一個新的 Entity ,然後將它當做參數傳遞給其中一個方法。 如果實體不存在,則每個方法都會插入實體。 如果實體已經存在,如果屬性已經存在, insertOrMergeEntity 就會更新屬性值,並在屬性不存在時新增屬性,而 insertOrReplaceEntity 會完全取代現有的實體。 下列範例示範如何使用 insertOrMergeEntity。 如果 「 PartitionKey tasksSeattle」 和 RowKey 「1」 的實體不存在,則會插入該實體。 不過,如果已經存在 (,如上一個範例) 所示,則會 DueDate 更新 屬性,並 Status 新增屬性。 DescriptionLocation 屬性也會更新,但是所使用的值實際上會讓它們保持不變。 如果未新增這兩個屬性,如範例所示,但存在於目標實體上,則其現有值會保持不變。

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 方法可讓您透過查詢其 PartitionKeyRowKey 來擷取單一實體。 在此範例中,數據分割索引鍵和數據列索引鍵tasksSeattle1會傳遞至 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。 下列範例示範如何透過將篩選條件傳遞給 queryEntities 方法來擷取 tasksSeattle 分割中的所有實體。

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之後,傳回的實體只會有選取的屬性。 如果您想要傳回 Table 實體的子集,請使用如先前查詢所示的篩選。

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

刪除實體

若要刪除實體,請將資料表名稱以及實體的 PartitionKeyRowKey 傳遞給 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 />";
}

針對並行檢查,您可以使用 DeleteEntityOptions->setEtag 方法為要刪除的實體設定 Etag,並將 DeleteEntityOptions 物件傳遞給 deleteEntity 作為第四個參數。

批次資料表作業

TableRestProxy->batch 方法可讓您以單一要求執行多項作業。 這裡的模式涉及將作業新增至 BatchRequest 物件,然後將 BatchRequest 物件傳遞給 TableRestProxy->batch 方法。 若要將作業新增至 BatchRequest 物件,您可以呼叫下列任一方法許多次:

Description
addInsertEntity 新增 insertEntity 作業
addUpdateEntity 新增 updateEntity 作業
addMergeEntity 新增 mergeEntity 作業
addInsertOrReplaceEntity 新增 insertOrReplaceEntity 作業
addInsertOrMergeEntity 新增 insertOrMergeEntity 作業
addDeleteEntity 新增 deleteEntity 作業

下列範例示範如何以單一要求執行 insertEntitydeleteEntity 作業。

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

如需有關批次處理資料表作業的詳細資訊,請參閱執行實體群組交易

刪除資料表

最後,若要刪除資料表,請將資料表名稱傳遞給 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 />";
}