Giter Club home page Giter Club logo

azure-storage-php's Introduction

Microsoft Azure Storage PHP Client Libraries (Deprecated)

This project will be in Community Support until 17 March 2024. After this date the project and associated client libraries will be retired permanently. For more details on the retirement and alternatives to using this project, visit Retirement notice: The Azure Storage PHP client libraries will be retired on 17 March 2024.


This project provides a set of PHP client libraries that make it easy to access Microsoft Azure Storage services (blobs, tables, queues and files). For documentation on how to host PHP applications on Microsoft Azure, please see the Microsoft Azure PHP Developer Center.

  • azure-storage-blob Latest Stable Version
  • azure-storage-table Latest Stable Version
  • azure-storage-queue Latest Stable Version
  • azure-storage-file Latest Stable Version
  • azure-storage-common Latest Stable Version

Note

  • If you are looking for the Service Bus, Service Runtime, Service Management or Media Services libraries, please visit Azure SDK for PHP.
  • If you need big file (larger than 2GB) or 64-bit integer support, please install PHP 7 64-bit version.

Features

  • Blobs
    • create, list, and delete containers, work with container metadata and permissions, list blobs in container
    • create block and page blobs (from a stream or a string), work with blob blocks and pages, delete blobs
    • work with blob properties, metadata, leases, snapshot a blob
  • Tables
    • create and delete tables
    • create, query, insert, update, merge, and delete entities
    • batch operations
  • Queues
    • create, list, and delete queues, and work with queue metadata and properties
    • create, get, peek, update, delete messages
  • Files
    • create, list, and delete file shares and directories
    • create, delete and download files

Please check details on API reference documents.

Minimum Requirements

  • PHP 5.6 or above

  • See composer.json for dependencies

  • Required extension for PHP:

    • php_fileinfo.dll
    • php_mbstring.dll
    • php_openssl.dll
    • php_xsl.dll
  • Recommended extension for PHP:

    • php_curl.dll

Download Source Code

To get the source code from GitHub, type

git clone https://github.com/Azure/azure-storage-php.git
cd ./azure-storage-php

Install via Composer

  1. Create a file named composer.json in the root of your project and add the following code to it:
{
  "require": {
    "microsoft/azure-storage-blob": "*",
    "microsoft/azure-storage-table": "*",
    "microsoft/azure-storage-queue": "*",
    "microsoft/azure-storage-file": "*"
  }
}
  1. Download composer.phar in your project root.

  2. Open a command prompt and execute this in your project root

php composer.phar install

Usage

There are four basic steps that have to be performed before you can make a call to any Microsoft Azure Storage API when using the libraries.

  • First, include the autoloader script:
require_once "vendor/autoload.php"; 
  • Include the namespaces you are going to use.

    To create any Microsoft Azure service client you need to use the rest proxy classes, such as BlobRestProxy class:

use MicrosoftAzure\Storage\Blob\BlobRestProxy;

To process exceptions you need:

use MicrosoftAzure\Storage\Common\ServiceException;
  • To instantiate the service client you will also need a valid connection string. The format is:
DefaultEndpointsProtocol=[http|https];AccountName=[yourAccount];AccountKey=[yourKey]

Or:

BlobEndpoint=myBlobEndpoint;QueueEndpoint=myQueueEndpoint;TableEndpoint=myTableEndpoint;FileEndpoint=myFileEndpoint;SharedAccessSignature=sasToken

Or if AAD authentication is used:

BlobEndpoint=myBlobEndpoint;QueueEndpoint=myQueueEndpoint;TableEndpoint=myTableEndpoint;FileEndpoint=myFileEndpoint;AccountName=[yourAccount]

Note that account name is required.

  • Instantiate a client object - a wrapper around the available calls for the given service.
$blobClient = BlobRestProxy::createBlobService($connectionString);
$tableClient = TableRestProxy::createTableService($connectionString);
$queueClient = QueueRestProxy::createQueueService($connectionString);
$fileClient = FileRestProxy::createFileService($connectionString);

Or for AAD authentication:

$blobClient = BlobRestProxy::createBlobServiceWithTokenCredential($token, $connectionString);
$queueClient = QueueRestProxy::createQueueServiceWithTokenCredential($token, $connectionString);

Note that Blob and Queue service supports AAD authentication.

Using Middlewares

To specify the middlewares, user have to create an array with middlewares and put it in the $requestOptions with key 'middlewares'. The sequence of the array will affect the sequence in which the middleware is invoked. The $requestOptions can usually be set in the options of an API call, such as MicrosoftAzure\Storage\Blob\Models\ListBlobOptions.

The user can push the middleware into the array with key 'middlewares' in services' $_options instead when creating them if the middleware is to be applied to each of the API call for a rest proxy. These middlewares will always be invoked after the middlewares in the $requestOptions. e.g.:

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

Each of the middleware should be either an instance of a sub-class that implements MicrosoftAzure\Storage\Common\Internal\IMiddleware, or a callable that follows the Guzzle middleware implementation convention.

User can create self-defined middleware that inherits from MicrosoftAzure\Storage\Common\Internal\Middlewares\MiddlewareBase.

Retrying failures

You can use bundled middlewares to retry requests in case they fail for some reason. First you create the middleware:

$retryMiddleware = RetryMiddlewareFactory::create(
    RetryMiddlewareFactory::GENERAL_RETRY_TYPE,  // Specifies the retry logic
    3,  // Number of retries
    1000,  // Interval
    RetryMiddlewareFactory::EXPONENTIAL_INTERVAL_ACCUMULATION,  // How to increase the wait interval
    true  // Whether to retry connection failures too, default false
);

Then you add the middleware when creating the service as explained above:

$optionsWithMiddlewares = [
    'middlewares' = [
        $retryMiddleware
    ],
];
$tableClient = TableRestProxy::createTableService(
    $connectionString,
    $optionsWithMiddlewares
);

Or by pushing it to the existing service:

$tableClient->pushMiddleware($retryMiddleware);

Following errors are not retried in current retry middleware:

  • Authentication failures.
  • "Resource Not Found" errors.
  • Guzzle request exceptions that does not bear an HTTP response, e.g. failed to open stream, or cURL Connection reset by peer, etc. Note: Community contribution to cover the Guzzle request exceptions are welcomed.

Retry types

  • RetryMiddlewareFactory::GENERAL_RETRY_TYPE - General type of logic that handles retry
  • RetryMiddlewareFactory::APPEND_BLOB_RETRY_TYPE * For the append blob retry only, currently the same as the general type

Interval accumulations

  • RetryMiddlewareFactory::LINEAR_INTERVAL_ACCUMULATION - The interval will be increased linearly, the nth retry will have a wait time equal to n * interval
  • RetryMiddlewareFactory::EXPONENTIAL_INTERVAL_ACCUMULATION - The interval will be increased exponentially, the nth retry will have a wait time equal to pow(2, n) * interval

Using proxies

To use proxies during HTTP requests, set system variable HTTP_PROXY and the proxy will be used.

Troubleshooting

Error: Unable to get local issuer certificate

cURL can't verify the validity of Microsoft certificate when trying to issue a request call to Azure Storage Services. You must configure cURL to use a certificate when issuing https requests by the following steps:

  1. Download the cacert.pem file from cURL site.

  2. Then either:

    • Open your php.ini file and add the following line:

      curl.cainfo = "<absolute path to cacert.pem>"

      OR

    • Point to the cacert in the options when creating the Relevant Proxy.

      //example of creating the FileRestProxy
      $options["http"] = ["verify" => "<absolute path to cacert.pem>"];
      FileRestProxy::createFileService($connectionString, $options);

Code samples

You can find samples in the samples folder.

Migrate from Azure SDK for PHP

If you are using Azure SDK for PHP to access Azure Storage Service, we highly recommend you to migrate to this SDK for faster issue resolution and quicker feature implementation. We are working on supporting the latest service features as well as improvement on existing APIs.

For now, Microsoft Azure Storage PHP client libraries share almost the same interface as the storage blobs, tables, queues and files APIs in Azure SDK for PHP. However, there are some minor breaking changes need to be addressed during your migration. You can find the details in BreakingChanges.md.

Need Help?

Be sure to check out the Microsoft Azure Developer Forums on Stack Overflow and github issues if you have trouble with the provided code.

Please note this project will be in Community Support and Azure Storage team commits to validate and release every quarter, as long as there are PRs from community. Azure Storage team is unable to continue to add new features or provide bugfixes.

Contribute Code or Provide Feedback

If you would like to become an active contributor to this project please follow the instructions provided in Azure Projects Contribution Guidelines. You can find more details for contributing in the CONTRIBUTING.md.

If you encounter any bugs with the library please file an issue in the Issues section of the project.

azure-storage-php's People

Contributors

carusogabriel avatar dluces avatar ganboonhong avatar hason-msft avatar jeffreylasut avatar jezmck avatar jondmcelroy avatar juliushaertl avatar katmsft avatar luxifer avatar manumsft avatar microsoft-github-policy-service[bot] avatar mmft24 avatar nowenl avatar nyholm avatar pawel-lewtak avatar sadika9 avatar schoag-msft avatar seanmcc-msft avatar sebastienwarin avatar sergey-shandar avatar shaked avatar simon-tma avatar spaze avatar subhaze avatar vinjiang avatar willmorgan avatar wslaghekke avatar xiaoningliu avatar z38 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

azure-storage-php's Issues

Unable to use Storage Emulator with tables

I'm having a fatal error with the SDK connecting to Table Storage through the Azure Storage Emulator. An OutOfRangeInput exception is thrown when trying to query/create tables specifically. All of my connection info is in lowercase format, and the same code works just fine on the live Azure storage.

Here's a sample of code that produces the problem:

// Works!
$this->__tableClient = ServicesBuilder::getInstance()->createTableService($this->__connectionString);
echo '<pre>', print_r($this->__tableClient->queryTables()), '</pre>';

// Fatal error :(
// I receive an instance of the table service, but any subsequent method throws exceptions.
$testClient = ServicesBuilder::getInstance()->createTableService('UseDevelopmentStorage=true;');
echo '<pre>', print_r($testClient->queryTables()), '</pre>';

I have also tried using a connection string specifying BlobEndpoint, TableEndpoint, and QueueEndpoint with the correct port and such, along with the well-known account and access key.

After digging through the code and exception, I can't seem to find anything more detailed than OutOfRangeInput and code 400. I even used Fiddler to check the request and couldn't get anything else.

BlobRestProxy::listBlobs issues with a prefix with a comma (,)

Reproduce

  1. Create a blob called: my dir, and that/subdir/blob.txt
  2. Try to list blobs inside the my dir, and that "directory"

Sample Code

$container_name = 'test-container';

$options = new ListBlobsOptions();
$options->setDelimiter('/');
$options->setPrefix('my dir, and that/')

try {
    // This will throw an exception for a 403 response
    $blob_list = $this->blob_proxy->listBlobs(
        $container_name,
        $options
    );
} catch (\Exception $e) {
    // ...
}

Error Response

Fail:
Code: 403
Value: Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
details (if any): <?xml version="1.0" encoding="utf-8"?><Code>AuthenticationFailed</Code><Message>Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
RequestId:bce16b9e-0001-0094-15dc-f4e755000000
Time:2016-08-12T20:59:37.6311976Z</Message><AuthenticationErrorDetail>The MAC signature found in the HTTP request '###' is not the same as any computed signature. Server used following string to sign: 'GET




application/x-www-form-urlencoded
Fri, 12 Aug 2016 20:59:38 GMT





x-ms-version:2015-04-05
/testaccount/test-container
comp:list
delimiter:/
prefix:my dir, and that/
restype:container'.</AuthenticationErrorDetail>.

Potential Issue
From the documentation to build the Canonicalized Resource String for 2009-09-19 and later Shared Key Format:

If a query parameter has more than one value, sort all values lexicographically, then include them in a comma-separated list:
parameter-name:parameter-value-1,parameter-value-2,parameter-value-n

I believe this is not being considered by the SDK, taking into account that the prefix does not seem to be able to have multiple values. For query parameters that cannot have more than one value, I would expect the SDK to do whatever is needed for it to be interpreted as a single value, and not many values (URL encoding the comma character prevents the error from being raised but it does not return the appropriate results).

Cannot upload images to Azure Storage (SSL error 60)

As of last week the Azure's storage uploader stopped working, the error message that I'm having is:

Server error. cURL error 60: SSL certificate problem: unable to get local issuer certificate (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)

My script its hosted on Azure web app as well, here are the basic details for it:
PHP: 7.0
Platform: 64 bit

I have two web apps running with exact same script and looks like both of them stopped working about the same time the library was updated - when I pushed my changes and the composer updated all of the libraries.

Non-verification of SSL certificates is hard-coded

Migrate from Azure/azure-sdk-for-php#758

ServicesBuilder:createBlobService() calls self::httpClient(); this gets a new HttpClient() (always with no parameters); and this in turn causes a new instantiation of \HTTP_Request2 with config parameters forcing SSL_VERIFY_PEER and SSL_VERIFY_HOST to false, and SSL_CAFILE to empty. So, there's not only no SSL verification - there's also no way to have SSL verification without replacing one of the classes.

On related notes (e.g. Azure/azure-sdk-for-php#747), I'd also add my voice to those proposing the removal of PEAR and HTTP_Request2 and switching to more modern/supported alternatives (like Guzzle).

Use static instead of parent to support easier extensibility

While wanting to work around #27, in my setup, it made sense to just extend MicrosoftAzure\Storage\Common\ServicesBuilder to override the blobAuthenticationScheme method to return an instance of an extended version of the SharedKeyAuthScheme class, where the workaround is applied. However, in ServicesBuilder, the getInstance method is creating an instance of its own class, when it could do static::$_instance = new static();, for example. This made me have to override the getInstance method accordingly. Also, the $_instance variable is private, so I had to use a different variable.
When extending MicrosoftAzure\Storage\Common\Internal\Authentication\SharedKeyAuthScheme, I would have expected to just need to override the computeCanonicalizedResource method. However, it was being called from the computeSignature where it actually called it like this: $canonicalizedResource = parent::computeCanonicalizedResource(...);. Using the parent keyword instead of the static keyword, made me have to override the computeSignature method as well.
Minor fixed in these classes would have made applying a workaround to the issue much faster and cleaner. It would be awesome to set this as the default practice to allow for better extensibility of the SDK.
As per the guidelines for contributing, I would need to have this discussed before creating a PR.

Create an asset from a existing blob

Copy from Azure/azure-sdk-for-php#915:

@cassianotartari

Hi!
I'm trying to figure out how to create an asset to streaming using an already uploaded video to blob storage. The storage is the same used in media services.
I've tried to use Iblob::copyBlob but it seems to not accept the asset as destination.
Now I'm thinking in use Iblob::getBlob to get file content and MediaServicesRestProxy::uploadAssetFile to set this content to my assetFile.
Is this the way?
Thanks.

Feedback Request on the Storage SDK backlog

Hi Everyone,

As we are working towards the GA version of our SDK, we are trying to prioritize our backlog based on user feedback. We have number of items like supporting latest REST API versions, as well as adding support for Files, Large Block Blobs and Incremental Copy. Let us know which of these are most important to you, and we will prioritize based on your feedback!

Azure Storage Team

Warnings when parsing non-XML strings in XmlSerializer

When parsing non-XML strings in XmlSerializer a warning is being returned.

Example warning:

Message: SimpleXMLElement::__construct(): {"odata.error":{"code":"ResourceNotFound","message":{"lang":"en-US","value":"The

The warning is generated in ServiceException::parseErrorMessage() because that's possibly parsing a non-XML string (as the comment try to parse using xml serializer, if failed, return the whole body suggests)

Sample backtrace:

File: /media/snafu-htdocs/report-uri/report-uri/application/libraries/Microsoft/vendor/microsoft/azure-storage/src/Common/Internal/Serialization/XmlSerializer.php
Line: 241
Function: __construct

File: /media/snafu-htdocs/report-uri/report-uri/application/libraries/Microsoft/vendor/microsoft/azure-storage/src/Common/Exceptions/ServiceException.php
Line: 89
Function: unserialize

File: /media/snafu-htdocs/report-uri/report-uri/application/libraries/Microsoft/vendor/microsoft/azure-storage/src/Common/Exceptions/ServiceException.php
Line: 70
Function: parseErrorMessage

Non XML strings should not generate a warning and I have a PR incoming where the warning is silenced by calling libxml_use_internal_errors(true).

Thanks for looking into this.

Urgent Problem with File Uploads

Hi there,

thanks for you really great Library.
Since we updated to 0.12 (on PHP 7.1). we face a Problem with Uploading some Files, which did not occur in previous Versions (funny enough, most Files work normally, but some Files dont).

A Test Scenario is the Upload of a local .zip File (1.8MB), which always fails.
Actually, when calling createBlockBlob(...), the Call is taking some Minutes, and then an Exception is thrown, which basically is a cURL Exception:
[errno] => 56
[error] => Recv failure: Connection reset by peer

After some Tests with the SDKs Code, I was able to make the Upload work again by removing "result=false" in \Storage\Common\Internal\Utilities::isStreamLargerThanSizeOrNotSeekable the Line 782.
TBH, I am not an Expert in PHP Streams, so I dont really understand, what the $strem->read(1)=="" is checking, but disabling this Check (= keeping "result=true") is leading to the correct Behavious.

The result of this Change is, that createBlockBlobByMultipleUploadAsync is called instead of createBlockBlobBySingleUploadAsync - so maybe the real Problem is in there?

Would be great if we could solve this Issue in a better way than removing some Lines in you Code:)

Thanks,
Christoph

BlobRestProxy::createBlockBlobByMultipleUploadAsync does not forward options to each upload request

When uploading a file that requires chunk uploads like this:

$options = new CreateBlobOptions();
$options->setTimeout(600);

$blob = $blob_proxy->createBlockBlob(
                $container_name,
                $blob_name,
                $content,
                $options
            );

The timeout is not really used in each chunk. This is because the CreateBlobBlockOptions are not being created from the CreateBlobOptions that we passed in (assuming the file requires to be uploaded in chunks).

I think BlobRestProxy::createBlockBlobByMultipleUploadAsync should initialize $createBlobBlockOptions like this:

        if (is_null($options)) {
            $options = new CreateBlobOptions();
        }

        $createBlobBlockOptions = CreateBlobBlockOptions::create($options);

Instead of:

        $createBlobBlockOptions = new CreateBlobBlockOptions();
        if (is_null($options)) {
            $options = new CreateBlobOptions();
        }

Otherwise, the $options (CreateBlobOptions) won't be forwarded to each chunk's upload request when calling $this->createBlobBlockQueryParams($createBlobBlockOptions, $blockId).

Namespaced tests broken on case-sensitive filesystems

When trying to run the unit tests, PHPUnit is unable to find all classes on a case-sensitive filesystem:

PHP Fatal error:  Class 'MicrosoftAzure\Storage\Tests\Framework\ServiceRestProxyTestBase' not found in /app/azure-storage-php/tests/framework/BlobServiceRestProxyTestBase.php on line 43

IMHO, the cleanest approach would be to convert the first letter of all subfolders in tests/ to uppercase. I'm happy to submit a pull-request, however the request should get merged relatively quickly to avoid merge conflicts.

As an alternative, the autoloader can be adjusted to avoid moving all test files.

Allow passing Guzzle client options

I want to be able to pass options to the Guzzle client (like HTTP timeout). I'm able to do this on the old SDK by setting up a request filter and doing something like $request->setConfig('timeout', $timeout), but this isn't available anymore.

Linux memory usage increment

I set up listBlobs sample run every 5 minutes by cron job.
Memory usage percentage increase from 15% to 30% after 1 days and to 40% after 2 days but is not auto released.
I dont know reason, is this SDK issues or another reason. Can you check my problem? Thank you

Failure to upload in v0.17.0

Environment: Azure Web Apps
PHP Version: 7.0 (Provided by Azure Web Apps)

I encountered following error when uploading a image with microsoft/[email protected]

<b>Fatal error</b>:  Uncaught Error: Call to undefined method MicrosoftAzure\Storage\Common\Internal\Validate::isString() in D:\home\site\wwwroot\vendor\microsoft\azure-storage\src\Blob\BlobRestProxy.php:1657
Stack trace:
#0 D:\home\site\wwwroot\vendor\microsoft\azure-storage\src\Blob\BlobRestProxy.php(1519): MicrosoftAzure\Storage\Blob\BlobRestProxy-&gt;createBlockBlobBySingleUploadAsync('image-upload', 'profile__e116da...', Object(GuzzleHttp\Psr7\Stream), NULL)
#1 D:\home\site\wwwroot\vendor\microsoft\azure-storage\src\Blob\BlobRestProxy.php(1477): MicrosoftAzure\Storage\Blob\BlobRestProxy-&gt;createBlockBlobAsync('image-upload', 'profile__e116da...', '\x89PNG\r\n\x1A\n\x00\x00\x00\rIHD...', NULL)
#2 D:\home\site\wwwroot\lib\myapp.php(130): MicrosoftAzure\Storage\Blob\BlobRestProxy-&gt;createBlockBlob('image-upload', 'profile__e116da...', '\x89PNG\r\n\x1A\n\x00\x00\x00\rIHD...')
#3 D:\home\site\wwwroot\uploadImage.php(41): MyApp\App-&gt;upload_to_blob('image-upload', 'profile__e116da...', '\x89PNG\r\n\x1A\n\x00\x00\x00\rIHD...')
#4 in <b>D:\home\site\wwwroot\vendor\microsoft\azure-storage\src\Blob\BlobRestProxy.php</b> on line <b>1657</b><br />

As temporary solution, I locked the version of microsoft/azure-storage as v0.16.0 in composer.json. Result, the problem was solved.

Why failure in v0.17.0 ?

Azure Table Query Bug

I observe extremely strange Query Results when querying a Table Storage Database - I may have an error in my code, but I cannot understand the results at all.

Very Simple Approach:

$connectionString="DefaultEndpointsProtocol=https;AccountName=...";
$tableRestProxy = \MicrosoftAzure\Storage\Common\ServicesBuilder::getInstance()->createTableService($connectionString);

$filter="PartitonKey eq 'shutdown'";
$result=$tableRestProxy->queryEntities(TABLE,$filter);

RESULT IS EMPTY (but shouldnt, there are tons of items with this PartitonKey)

Now I try to use a correct QueryEntitiesOptions Object:

$filter=new \MicrosoftAzure\Storage\Table\Models\QueryEntitiesOptions();
$filter->setFilter("PartitionKey eq 'shutdown'");
$result=$tableRestProxy->queryEntities(TABLE,$filter);

RESULT IS EMPTY (but shouldnt, there are tons of items with this PartitonKey)

Now I add a Projection:

$filter=new \MicrosoftAzure\Storage\Table\Models\QueryEntitiesOptions();
$filter->setFilter("PartitionKey eq 'shutdown'");
$filter->addSelectField('PartitionKey');
$result=$tableRestProxy->queryEntities(TABLE,$filter);

RESULT IS NOT EMPTY (many items are returned, but from all possible PartitionKeys, not only the one specified in the Filter).

So basically, Im completely without any clue here :)
Its just a normal Table (ok, some fields contain really huge Text Strings, thats why I added the Projection) - but none of these responses is correct.

I can send you the Endpoint Data privately, if you wanna try. It would be really great, if thats my fault, because we need this Logic on a big scale very soon.

Thanks,
Christoph

Azure Storage PHP Client Library GA Notice

Hi,

Azure Storage PHP Client Library is going for the GA release in the next following month. During the GA release, we will split the 1 azure-storage composer package into at least 4 storage service packages: azure-storage-blob, azure-storage-table, azure-storage-queue and azure-storage-file. This will provide more flexibility for customers who doesn't want to depend on multi Azure storage services at the same time. Any comments are welcome!

Best

ConnectionStringParser::_createException incorrectly calls sprintf

sprintf accepts a variable number of arguments, while an array needs to be passed here instead. An alternative is to call vsprintf instead.

You can test this error like this:

use MicrosoftAzure\Storage\Common\Internal\StorageServiceSettings;

StorageServiceSettings::createFromConnectionString('invalid');

You can see a simple fix for this here.

Stream wrapper?

Migrate from Azure/azure-sdk-for-php#706

It looks to me like this SDK does not have a facility to register a stream wrapper for blob storage, like the old SDK did - https://phpazure.codeplex.com/wikipage?title=Blob%20storage%20stream%20wrapper - is this correct?

If it is correct, then I'd like to express interest in one. I am the lead developer for UpdraftPlus - http://wordpress.org/plugins/updraftplus - which was the most downloaded WordPress backup plugin in 2013. I'd love to have a back-end for Windows Azure storage, and it can happen a lot quicker if I there's a stream wrapper (we've already got a generic class for this).

Many thanks,
David

copyBlob generates incorrect x-ms-copy-source header

When using copyBlob it will generate a full URI however when it calls the method getUri it will return a string that ends in a /. Since containerNames must start with a / this causes a double up of slashes for the header value.

It currently generates like
https://something.blob.core.windows.net//1234/photo/1.png

However it should be
https://something.blob.core.windows.net/1234/photo/1.png

Container name with incorrect <space> causes Mac Validation error

Migrated from: Azure/azure-sdk-for-php#798

I incorrectly tried to call listBlobs with a container name that had a space in it "uploaded files" instead of "uploadedfiles", which is an illegal name. I would have expected a straight-forward exception to be thrown but instead, was shown the dreaded: The MAC signature found in the HTTP request ... is not the same as any computed signature.

This took me hours to fix because it looked like a much more serious error than it really was (did I need to manually compute the signature etc.).

I guess that any API call that requires a conforming name to be passed for container or blob name should validate the format in the SDK and throw an exception rather than pass the call to the API. It would also be nice if the API itself returned a more useful error but that is someone else's problem.

wrong XMLSerializer in ServiceException.php

ServiceException class uses wrong XMLSerializer. There is no such file exists it suppose to be MicrosoftAzure\Storage\Common\Internal\Serialization\ XmlSerializer.
I tried to create pull request for fix but i guess i don't have permission.

listBlobsOptions has been removed ?

I am trying to get blob with a specific prefix. But i am not able to execute the function. here is the code$blobListOptions = new ListBlobsOptions(); $blobListOptions->setPrefix('test/'); $blob_list = $blobRestProxy->listBlobs($container_name,$blobListOptions);

From Azure/azure-sdk-for-php#930

[Notification] Upcoming breaking change for next release

Hi All,

In the next release, we'll have the following breaking changes as below. Please let us know in case of any issues!

  1. MicrosoftAzure\Storage\Common\Internal\InvalidArgumentTypeException will be moved to MicrosoftAzure\Storage\Common\Exceptions\InvalidArgumentTypeException
  2. MicrosoftAzure\Storage\Common\ServiceException will be moved to MicrosoftAzure\Storage\Exceptions\ServiceException
  3. MicrosoftAzure\Storage\Common\Internal\HttpFormatter will be moved to MicrosoftAzure\Storage\Common\Internal\Http\HttpFormatter
  4. MicrosoftAzure\Storage\Common\ServiceOptionsBase will be moved to MicrosoftAzure\Storage\Common\Internal\ServiceOptionsBase
  5. MicrosoftAzure\Storage\Common\Internal\Logger will be moved to MicrosoftAzure\Storage\Common\Logger
  6. MicrosoftAzure\Storage\Common\Internal\Middlewares\HistoryMiddleware will be moved to MicrosoftAzure\Storage\Common\Middlewares\HistoryMiddleware
  7. MicrosoftAzure\Storage\Common\Internal\IMiddleware will be moved to MicrosoftAzure\Storage\Common\Middlewares\IMiddleware
  8. MicrosoftAzure\Storage\Common\Internal\Middlewares\MiddlewareBase will be moved to MicrosoftAzure\Storage\Common\Middlewares\MiddlewareBase
  9. MicrosoftAzure\Storage\Common\Internal\RetryMiddlewareFactory will be moved to MicrosoftAzure\Storage\Common\Middlewares\RetryMiddlewareFactory

Haibo Song,
Azure Storage Team

Notice on upcoming Breaking Change.

Dear all,

This is a short notice for upcoming breaking change that will occur in the next release.

Strong Type

After some internal discussion, strong type(a.k.a type hinting) will be applied to the current SDK. The general rules for the strong type is listed below:

  1. For ‘int’, ’string’ and mixed type that accept multiple types, do not use strong type.
  2. For ‘array’, ‘callable’ and other self-defined or user defined type, use strong type to indicate the type.

Change of return value of some APIs

E.g. createBlobBlock and createBlockBlob returns CopyBlobResult, which does not seem to be correct.

There are possibly other breaking changes that will be updated once finalized.

MD5 verification for chunked blob uploads is not working

When uploading a large blob, before we could do setBlobContentMD5() and that would set the MD5 for the whole blob, which would be verified during the commit step. When refactoring the CreateBlobOptions in 0.15.0 to remove setBlobContentMD5 in favour of setContentMD5, the MD5 hash for the whole blob was being used in each of the chunk's request. This made the requests fail the validation as the MD5 hash passed would not match the content for the specific chunk (instead, it would match the content for the whole blob).

This fixes the issue by NOT adding the ContentMD5 to each blob block. It would be nice if each blob block would be verified if the content MD5 is set in the CreateBlobOptions but that could be another issue.

Use \DateTime for SharedAccessSignatureHelper $signedExpiry and $signedStart instead of string

While creating a SAS token, you should enforce expiry start and end date times to actually be \DateTime instead of string looking like one. Reason is, you're then able to properly format them before pushing into generateServiceSharedAccessSignatureToken.

I bring this up as I've been using $dateTime->format('c') which passes the current validation, but SAS token will fail as used. Problem is, it's generates YYYY-MM-DDTHH:MM:SS+00:00 instead of YYYY-MM-DDTHH:MM:SSZ which was quite hard to track down.

Doesn't Support SAS Authentication

Migrate from Azure/azure-sdk-for-php#733

This makes this library nearly unusable from a perspective of integration scenarios where you are trying to work across vendors or companies. Given that this is a potentially major use case for queues, this is glaring. We got burned, had to redo our work and went to just plain curl / php guzzle. Would have been good to at least now this up front.

Isssue installing Microsoft Azure Storage Library for PHP via composer

we are trying to install Microsoft Azure Storage Library for PHP but getting some weird errors which we googled and it returned nothing, here is what we did

  1. Cloned the repo from github
  2. Composer install (see image for error)

here is what we got as result of that(for seo purpose or in case image is not loaded correctly)

Your requirements could not be resolved to an installable set of packages.

Problem 1
- theseer/phpdox 0.8.1.1 requires ext-xsl * -> the requested PHP extension xsl is missing from your system.
- theseer/phpdox 0.8.1 requires ext-xsl * -> the requested PHP extension xsl is missing from your system.
- theseer/phpdox 0.8.0 requires ext-xsl * -> the requested PHP extension xsl is missing from your system.
- Installation request for theseer/phpdox ~0.8 -> satisfiable by theseer/phpdox[0.8.0, 0.8.1, 0.8.1.1].

To enable extensions, verify that they are enabled in those .ini files:
- /etc/php5/cli/php.ini
- /etc/php5/cli/conf.d/05-opcache.ini
- /etc/php5/cli/conf.d/10-pdo.ini
- /etc/php5/cli/conf.d/20-curl.ini
- /etc/php5/cli/conf.d/20-gd.ini
- /etc/php5/cli/conf.d/20-json.ini
- /etc/php5/cli/conf.d/20-mysql.ini
- /etc/php5/cli/conf.d/20-mysqli.ini
- /etc/php5/cli/conf.d/20-pdo_mysql.ini
- /etc/php5/cli/conf.d/20-readline.ini
You can also run php --ini inside terminal to see which files are used by PHP in CLI mode.

After this as instructed we ran php --ini

here is the exact output(for seo or image not loaded properly)

Configuration File (php.ini) Path: /etc/php5/cli
Loaded Configuration File: /etc/php5/cli/php.ini
Scan for additional .ini files in: /etc/php5/cli/conf.d
Additional .ini files parsed: /etc/php5/cli/conf.d/05-opcache.ini,
/etc/php5/cli/conf.d/10-pdo.ini,
/etc/php5/cli/conf.d/20-curl.ini,
/etc/php5/cli/conf.d/20-gd.ini,
/etc/php5/cli/conf.d/20-json.ini,
/etc/php5/cli/conf.d/20-mysql.ini,
/etc/php5/cli/conf.d/20-mysqli.ini,
/etc/php5/cli/conf.d/20-pdo_mysql.ini,
/etc/php5/cli/conf.d/20-readline.ini

Now according to our assumption, required extensions are there but we are unable to find what exactly is the problem.

Originally Posted on stackoverflow

Add async methods

It would be nice if there were async methods for calls, or a toggle to specify whether or not the method will use async and return a promise.

Is there wiki page for all the function names that we can use for different classes.

I might be missing something but is there any wiki page which shows all the function names and its input value details. This is example i was more talking about So i was trying to get the blob from container and store in specific file name. This url gave me example how to download the blob but after looking into BlobSamples i was able to get the correct function. So i was wondering if we come up with some wiki page which have all the function name and its use on one page then it would be useful to search things. This is just example. Not necessary that detail but something like that on wiki page. I am ready to contribute.

getContentStream out of memory due to not being a true stream

getContentStream should return a true stream so allowing for large file downloads.

Currently it pulls the full file into memory before streaming out.

Which obviously causes php to run out of memory on large files.

Either it should be a true stream or rather then don't refer to it as a stream, which it isn't in the true sense, but download or something similar.

Otherwise people will get confused.

PhpDoc blocks note using prefix \ for all return types.

Currently the phpdoc blocks are not using the prefixed \ (root) before return class notation. This causes some IDE's to not show autocompletion (JetBrains).

Sample fix in https://github.com/Azure/azure-storage-php/blob/master/src/Blob/BlobRestProxy.php#L715

    /**
     * Lists all of the containers in the given storage account.
     * 
     * @param Models\ListContainersOptions $options The optional parameters.
     * 
     * @return \MicrosoftAzure\Storage\Blob\Models\ListContainersResult
     *         ^ Adding the root prefix will fix autocompletion on some IDE's
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179352.aspx
     */

I can change this myself and open pull if wanted to adopt the root() prefix.

Even more issues are there when there is no full namespace defined in return, but relative. Some IDE's will not get the correct namespace path.

Call upon all entity properties?

Currently when creating the ticket, the only way to call upon entity properties is by using
$entity->getProperty("<property>")

Replacing with the property you would like to retrieve. There is no way to retrieve all properties at once.

Suppose you could make an option for this? Because if entity 1 has the property 1 and 2 while entity 2 has the property 1 and we do a query where both entity comes up as results but we call property 1 and 2 we will encounter an error.

Is there a workaround for this?

Add support for generation of SAS tokens/signed URLs

We have some code to generate service SAS that we're willing to contribute back to this repo. What would be the best place to put a method to generate service SAS tokens?

Also, @jcorioland published a gist with code to generate Account SAS tokens that would be helpful to have as part of the SDK too.

Storing PHP sessions in Azure Table Storage

Migrate from Azure/azure-sdk-for-php#680

In this Windows Azure SDK for PHP, it looks like doesn't implemented a Session Handler for PHP. I was found that there is do exist in the CodePlex project, but it just said "Deprecated in favor of the new SDK on GitHub".

So are you going to implement a new version of PHP Session Handler in this new Windows Azure SDK for PHP?

set medadate when creating blockblob doesn't work

It seems that there is a mistake at https://github.com/Azure/azure-storage-php/blob/master/src/Blob/Models/CreateBlobOptions.php#L399, which describes the setMetadata() function in MicrosoftAzure\Storage\Blob\Models\CreateBlobOptions should receive a string param, but in my test, when set string, it will raise a exception similar as Fatal error: Uncaught MicrosoftAzure\Storage\Common\Internal\InvalidArgumentTypeException: The provided variable 'metadata' should be of type 'array' in E:\Projects\PHP\azure-storage-php\code_sample\vendor\microsoft\azure-storage\src\Common\Internal\Validate.php.

But if I set an array param in this function, the blob upload to Azure storage successfully, but without any metadata. The same issue when I use CommitBlobBlocksOptions() model.

Is it a bug, or is there a mistake when I using the option models?

Remove version tags in each of the files.

Currently the project has version tag embedded in each of the file. The reason is that the project used to use PEAR to publish and it is PEAR's requirement. Now that the project uses Packagist which no longer requires those tags I am thinking about removing them in the next release. Any concerns by the community?

Reuse existing GuzzleHTTP clients

I had a use case for creating many block blobs (65000+) at once to cache records in a database. However, the library would consistently throw an exception after the 2000th createBlockBlob call:

cURL error 7: Failed to connect to ***.blob.core.windows.net port 443: Address already in use (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)

While troubleshooting, I found that ServiceRestProxy (inherited by BlobRestProxy) instantiates a new GuzzleHttp\Client on every call, whereas examples in the Guzzle documentation
reuse a single Client object across multiple requests. It seems that each Client object uses up its own outbound port, eventually exhausting the available ports on the server.

I was able to fix the issue by modifying ServiceRestProxy->sendAsync to reuse the Client object. I created a method in ServiceRestProxy that checks whether a GuzzleHttp\Client with provided $clientOptions has been created before. If not, the method would call ServiceRestProxy->createClient and return the resulting object.

I've submitted a PR at #57.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.