microsoft/azure-storage
Deprecated PHP client libraries for Microsoft Azure Storage (Blob, Table, Queue, File). Provides APIs to create/list/delete containers, blobs, tables, entities, queues, and metadata. In community support until 17 Mar 2024, then retired.
## Getting Started
### Minimal Setup for Laravel Integration
1. **Install via Composer** (in `composer.json`):
```json
"require": {
"microsoft/azure-storage-blob": "^1.5.4",
"microsoft/azure-storage-table": "^1.1.6",
"microsoft/azure-storage-queue": "^1.3.4",
"microsoft/azure-storage-file": "^1.2.5"
}
Run composer install.
Publish Configuration (optional but recommended): Create a config file for Azure credentials:
php artisan vendor:publish --provider="MicrosoftAzure\Storage\Common\StorageSettings" --tag=config
Update config/azure-storage.php with your connection string:
return [
'connection_string' => env('AZURE_STORAGE_CONNECTION_STRING'),
'default_service' => 'blob', // blob|table|queue|file
];
First Use Case: Upload a Blob
use MicrosoftAzure\Storage\Blob\BlobRestProxy;
use MicrosoftAzure\Storage\Common\ServiceException;
$connectionString = config('azure-storage.connection_string');
$blobClient = BlobRestProxy::createBlobService($connectionString);
try {
$blobName = 'test-blob-' . time() . '.txt';
$blobClient->createBlockBlob('my-container', $blobName, fopen('test.txt', 'r'));
Log::info("Blob uploaded successfully: $blobName");
} catch (ServiceException $e) {
Log::error("Blob upload failed: " . $e->getMessage());
}
Singleton Pattern for Clients: Create a Laravel service provider to initialize clients once:
// app/Providers/AzureStorageServiceProvider.php
public function register()
{
$this->app->singleton('azure.blob', function ($app) {
return BlobRestProxy::createBlobService(config('azure-storage.connection_string'));
});
// Repeat for table, queue, file services
}
Bind in config/app.php:
'azure' => [
'blob' => env('AZURE_BLOB_SERVICE', 'azure.blob'),
'table' => env('AZURE_TABLE_SERVICE', 'azure.table'),
],
Dynamic Service Selection: Use a facade or helper to switch services dynamically:
// app/Helpers/AzureHelper.php
public static function getService($type = 'blob')
{
return app("azure.$type");
}
Upload/Download with Streams:
// Upload from Laravel storage
$stream = Storage::disk('local')->readStream('file.pdf');
$blobClient->createBlockBlob('container', 'remote-file.pdf', $stream);
// Download to Laravel storage
$blob = $blobClient->getBlob('container', 'remote-file.pdf');
Storage::disk('local')->put('downloaded-file.pdf', $blob->getContent());
Batch Operations:
Use ListBlobOptions for pagination:
$blobs = [];
$listBlobsOptions = new ListBlobOptions();
$listBlobsOptions->setPrefix('prefix/');
$blobList = $blobClient->listBlobs('container', $listBlobsOptions);
foreach ($blobList as $blob) {
$blobs[] = $blob->getName();
}
// app/Models/AzureUser.php
class AzureUser extends Model implements ITableEntity
{
use Notifiable;
public $partitionKey;
public $rowKey;
public $timestamp;
public $etag;
}
Use a repository pattern:
// app/Repositories/AzureTableRepository.php
public function saveEntity($entity)
{
$tableClient = TableRestProxy::createTableService(config('azure-storage.connection_string'));
$tableClient->insertOrReplaceEntity('Users', $entity);
}
// app/Providers/QueueServiceProvider.php
public function boot()
{
Queue::extend('azure', function ($app) {
return new AzureQueueConnection(
Queue::connection('azure')->getQueue(),
config('azure-storage.connection_string')
);
});
}
Push jobs to Azure Queue:
Queue::connection('azure')->push('process-order', $orderData);
$sasToken = $fileClient->createSharedAccessSignature(
'share',
'directory/file.txt',
new SharedAccessSignaturePermissions('r'),
new SharedAccessExpiryTime('2023-12-31T23:59:59Z')
);
$url = $fileClient->getFileServiceProperties()->getPrimaryEndpoint() .
'/share/directory/file.txt?' . $sasToken;
Logging Middleware: Log all Azure Storage requests/responses:
$logMiddleware = new class implements IMiddleware {
public function handle($request, $handler) {
Log::debug('Azure Request: ' . $request->getUri());
$response = $handler->handle($request);
Log::debug('Azure Response: ' . $response->getStatusCode());
return $response;
}
};
$options = ['middlewares' => [$logMiddleware]];
$blobClient = BlobRestProxy::createBlobService($connectionString, $options);
Retry Middleware: Enable retries for transient failures:
$retryMiddleware = RetryMiddlewareFactory::create(
RetryMiddlewareFactory::GENERAL_RETRY_TYPE,
3,
1000,
RetryMiddlewareFactory::EXPONENTIAL_INTERVAL_ACCUMULATION
);
$blobClient->pushMiddleware($retryMiddleware);
// app/Listeners/HandleBlobUpload.php
public function handle(BlobUploaded $event)
{
// Process uploaded blob (e.g., generate thumbnail)
}
Dispatch events manually or use a queue job to poll for new blobs.Connection String Security:
.env:
AZURE_STORAGE_CONNECTION_STRING=DefaultEndpointsProtocol=https;AccountName=...;AccountKey=...;EndpointSuffix=core.windows.net
.env file in production.AAD Authentication: For Azure Active Directory authentication, use the token credential method:
$token = 'your-access-token';
$blobClient = BlobRestProxy::createBlobServiceWithTokenCredential(
$token,
'DefaultEndpointsProtocol=https;AccountName=...;EndpointSuffix=core.windows.net'
);
Large File Handling:
createPageBlob for files > 512MB or when random writes are needed.createBlockBlob with setBlobContentMD5 for integrity checks:
$blobClient->createBlockBlob(
'container',
'large-file.zip',
fopen('large-file.zip', 'r'),
null,
null,
['blobContentMD5' => md5_file('large-file.zip')]
);
Batch Operations:
TableBatch:
$batch = new TableBatch();
foreach ($entities as $entity) {
$batch->insertEntity($entity);
}
$tableClient->submitTableBatch('table-name', $batch);
Common Exceptions:
ServiceException: Wrap in try-catch blocks. Check $e->getCode() for HTTP status codes.Logging: Enable Guzzle logging for HTTP details:
$options = [
'http' => [
'debug' => fopen('azure-debug.log', 'w'),
'verify' => false, // Only for testing; use cacert.pem in production
]
];
SSL/TLS Issues:
How can I help you explore Laravel packages today?