microsoft/windowsazure
PHP client libraries for Microsoft Azure Tables, Blobs, Storage Queues, Service Bus, and runtime/management APIs. Note: this SDK is retired (since Feb 2021) and no longer maintained; use Azure REST APIs or azure-storage-php for Storage.
Installation:
composer require microsoft/windowsazure
Add to composer.json:
"require": {
"microsoft/windowsazure": "^0.5"
}
Autoload & Connection:
require_once __DIR__ . '/vendor/autoload.php';
use WindowsAzure\Common\ServicesBuilder;
use WindowsAzure\Common\ServiceException;
First Use Case (Blob Storage):
$connectionString = 'DefaultEndpointsProtocol=https;AccountName=YOUR_ACCOUNT;AccountKey=YOUR_KEY';
$blobService = ServicesBuilder::getInstance()->createBlobService($connectionString);
// Upload a file
$file = fopen('local-file.txt', 'r');
$blobService->createBlockBlob('container-name', 'blob-name', $file);
fclose($file);
Service Initialization:
$connectionString = env('AZURE_STORAGE_CONNECTION_STRING');
$services = ServicesBuilder::getInstance();
$blobService = $services->createBlobService($connectionString);
$tableService = $services->createTableService($connectionString);
$queueService = $services->createQueueService($connectionString);
CRUD Operations (Blob Example):
// Create container (idempotent)
$blobService->createContainer('my-container');
// Upload blob (stream or string)
$blobService->createBlockBlob('my-container', 'blob.txt', fopen('local.txt', 'r'));
// List blobs
$blobs = $blobService->listBlobs('my-container');
foreach ($blobs->getBlobs() as $blob) {
echo $blob->getName();
}
// Delete blob
$blobService->deleteBlob('my-container', 'blob.txt');
Table Operations:
// Insert entity
$entity = new \MicrosoftAzure\Storage\Table\Models\Entity();
$entity->setPartitionKey('partition1');
$entity->setRowKey('row1');
$entity->addProperty('name', \MicrosoftAzure\Storage\Table\Models\EdmType::STRING, 'Test');
$tableService->insertEntity('table-name', $entity);
// Query entities
$filter = "PartitionKey eq 'partition1'";
$result = $tableService->queryEntities('table-name', $filter);
foreach ($result->getEntities() as $entity) {
echo $entity->getProperty('name');
}
Queue Operations:
// Create queue
$queueService->createQueue('my-queue');
// Send message
$queueService->createMessage('my-queue', 'Hello Azure!');
// Get messages
$messages = $queueService->getMessages('my-queue');
foreach ($messages as $message) {
echo $message->getMessage();
$queueService->deleteMessage('my-queue', $message->getId(), $message->getPopReceipt());
}
Error Handling:
try {
$blobService->createBlockBlob('container', 'blob.txt', fopen('file.txt', 'r'));
} catch (ServiceException $e) {
log::error("Azure Error: {$e->getCode()}: {$e->getMessage()}");
// Handle specific HTTP codes (e.g., 404 for missing container)
if ($e->getCode() === 404) {
$blobService->createContainer('container');
}
}
Environment Variables:
Store connection strings in .env:
AZURE_STORAGE_CONNECTION_STRING=DefaultEndpointsProtocol=https;AccountName=...;AccountKey=...
AZURE_SERVICE_BUS_CONNECTION_STRING=Endpoint=sb://...;SharedSecretIssuer=...;SharedSecretValue=...
Dependency Injection:
Bind services in Laravel’s AppServiceProvider:
public function register()
{
$this->app->singleton('azure.blob', function ($app) {
return ServicesBuilder::getInstance()->createBlobService(env('AZURE_STORAGE_CONNECTION_STRING'));
});
}
Batch Operations:
Use TableBatch for bulk inserts/updates:
$batch = new \MicrosoftAzure\Storage\Table\Models\TableBatch();
$batch->insertEntity($entity1);
$batch->insertEntity($entity2);
$tableService->submitBatch('table-name', $batch);
Async Processing: Offload queue processing to a Laravel queue worker:
Queue::push(new ProcessAzureQueueJob('my-queue'));
Logging: Wrap SDK calls in logging middleware:
$start = microtime(true);
$blobService->createBlockBlob(...);
Log::debug("Blob upload took: " . (microtime(true) - $start) . "s");
Connection Strings:
UseDevelopmentStorage=true for local testing.SharedSecretIssuer and SharedSecretValue are correct (not AccountKey).Entity Limits:
PartitionKey and RowKey.Error Codes:
Timeouts:
$blobService->setTimeout(60); // 60 seconds
Deprecation:
Enable Debugging:
ServicesBuilder::getInstance()->withLogger(new \Monolog\Logger('azure'), \Monolog\Logger::DEBUG);
Check HTTP Headers:
Use Guzzle middleware to inspect requests:
$client = new \GuzzleHttp\Client(['debug' => true]);
Common Fixes:
AccountKey or SAS token.setTimeout() or optimize batch sizes.PartitionKey/RowKey match exactly.Custom Metadata: Add metadata to blobs/containers/queues:
$options = new \WindowsAzure\Blob\Models\CreateContainerOptions();
$options->addMetaData('custom-key', 'custom-value');
$blobService->createContainer('container', $options);
SAS Tokens: Generate shared access signatures for delegated access:
$sasToken = $blobService->generateSharedAccessSignature(
'container',
'blob.txt',
'r', // read permission
new \DateTime('+1 hour')
);
Event Subscriptions: Use Azure Storage Events (via Event Grid) for async notifications:
// Requires additional setup with Azure Event Grid
$eventGridTopic->sendEvent(new BlobCreatedEvent($blob));
Retry Logic: Implement exponential backoff for transient failures:
$retryPolicy = new \WindowsAzure\Common\RetryPolicy\ExponentialBackoffPolicy();
$blobService->setRetryPolicy($retryPolicy);
Local Testing: Use the Azure Storage Emulator (requires Docker or local install):
docker run -p 10000:10000 mcr.microsoft.com/azure-storage/azurite
Connection string: UseDevelopmentStorage=true.
How can I help you explore Laravel packages today?