Category: PHP

Version 3 Preview of the AWS SDK

by Jeremy Lindblom | on | in PHP | Permalink | Comments |  Share

We’re excited to introduce you to the preview release of Version 3 of the AWS SDK for PHP! As of today, the preview release of Version 3 (V3) is available on GitHub and via Composer.

Two years ago, we released Version 2 (V2) of the SDK. Since then, thousands of developers and companies have adopted it. We are sincerely grateful to all of our users and contributors. We have been constantly collecting your feedback and ideas, and continually watching the evolution of PHP, AWS, and the Guzzle library.

Earlier this year, we felt we could make significant improvements to the SDK, but only if we could break a few things. Since receiving a unanimously positive response to our blog post about updating to the latest version of Guzzle a few months ago, we’ve been working hard on V3, and we’re ready to share it with you.

What’s new?

The new version of the SDK provides a number of important benefits to AWS customers. It is smaller and faster, with improved performance for both serial and concurrent requests. It has several new features based on its use of the new Guzzle 5 library (which also includes the new features from Guzzle 4). The SDK will also, starting from V3, follow the official SemVer spec, so you can have complete confidence when setting version constraints in your projects’ composer.json files.

Let’s take a quick look at some of the new features.

Asynchronous requests

With V3, you can perform asynchronous operations, which allow you to more easily send requests concurrently. To achieve this, the SDK returns future result objects when you specify the @future parameter, which block only when they are accessed. For managing more robust asynchronous workflows, you can retrieve a promise from the future result, to perform logic once the result becomes available or an exception is thrown.


// Upload a file to your bucket in Amazon S3.
// Use '@future' to make the operation complete asynchronously.
$result = $s3Client->putObject([
    'Bucket' => 'your-bucket',
    'Key'    => 'docs/file.pdf',
    'Body'   => fopen('/path/to/file.pdf', 'r'),
    '@future' => true,

After creating a result using the @future attribute, you now have a future result object. You can use the data stored in the future in a blocking (or synchronous) manner by just using the result as normal (i.e., like a PHP array).

// Wait until the response has been received before accessing its data.
echo $result['ObjectURL'];

If you want to allow your requests to complete asynchronously, then you should use the promise API of the future result object. To retrieve the promise, you must use the then() method of the future result, and provide a callback to be completed when the promise is fulfilled. Promises allow you to more easily compose pipelines when dealing with asynchronous results. For example, we could use promises to save the Amazon S3 object’s URL to an item in an Amazon DynamoDB table, once the upload is complete.

// Note: $result is the result of the preceding example's PutObject operation.
    function ($s3Result) use ($ddbClient) {
        $ddbResult = $ddbClient->putItem([
            'TableName' => 'your-table',
            'Item' => [
                'topic' => ['S' => 'docs'],
                'time'  => ['N' => (string) time()],
                'url'   => ['S' => $s3Result['ObjectURL']],
            '@future' => true,

        // Don't break promise chains; return a value. In this case, we are returning
        // another promise, so the PutItem operation can complete asynchronously too.
        return $ddbResult->promise();
    function ($result) {
        echo "SUCCESS!n";
        return $result;
    function ($error) {
        echo "FAILED. " . $error->getMessage() . "n";
        // Forward the rejection by re-throwing it.
        throw $error;

The SDK uses the React/Promise library to provide the promise functionality, allowing for additional features such as joining and mapping promises.

JMESPath querying of results

The result object also has a new search() method that allows you to query the result data using JMESPath, a query language for JSON (or PHP arrays, in our case).


$result = $ec2Client->describeInstances();


Example output:

    [0] => i-xxxxxxxx
    [1] => i-yyyyyyyy
    [2] => i-zzzzzzzz

Swappable and custom HTTP adapters

In V3, cURL is no longer required, but is still used by the default HTTP adapter. However, you can use other HTTP adapters, like the one shipped with Guzzle that uses PHP’s HTTP stream wrapper. You can also write custom adapters, which opens up the possibility of creating an adapter that integrates with a non-blocking event loop like ReactPHP.


Paginators are a new feature in V3, that come as an addition to Iterators from V2. Paginators are similar to Iterators, except that they yield Result objects, instead of items within a result. This is nice, because it handles the tokens/markers for you, getting multiple pages of results, but gives you the flexibility to extract whatever data you want.

// List all "directories" and "files" in the bucket.
$paginator = $s3->getPaginator('ListObjects', [
    'Bucket' => 'my-bucket',
    'Delimiter' => '/'
foreach ($paginator as $result) {
    $jmespathExpr = '[CommonPrefixes[].Prefix, Contents[].Key][]';
    foreach ($result->search($jmespathExpr) as $item) {
        echo $item . "n";

Example output:

    [0] => dir1/
    [1] => dir2/
    [2] => file1
    [3] => file2

New event system

Version 3 features a new and improved event system. Command objects now have their own event emitter that is decoupled from the HTTP request events. There is also a new request "progress" event that can be used for tracking upload and download progress.

use GuzzleHttpEventProgressEvent;

$s3->getHttpClient()->getEmitter()->on('progress', function (ProgressEvent $e) {
    echo 'Uploaded ' . $e->uploaded . ' of ' . $e->uploadSize . "n";

   'Bucket' => $bucket,
   'Key'    => 'docs/file.pdf',
   'Body'   => fopen('/path/to/file.pdf', 'r'),

Example output:

Uploaded 0 of 5299866
Uploaded 16384 of 5299866
Uploaded 32768 of 5299866
Uploaded 5275648 of 5299866
Uploaded 5292032 of 5299866
Uploaded 5299866 of 5299866

New client options

For V3, we changed some of the options you provide when instantiating a client, but we added a few new options that may help you work with services more easily.

  • "debug" – Set to true to print out debug information as requests are being made. You’ll see how the Command and Request objects are affected during each event, and an adapter-specific wire log of the request.
  • "retries" – Set the maximum number of retries the client will perform on failed and throttled requests. The default has always been 3, but now it is easy to configure.

These options can be set when instantiating client.


$s3 = (new AwsSdk)->getS3([
    // Exist in Version 2 and 3
    'profile'  => 'my-credential-profile',
    'region'   => 'us-east-1',
    'version'  => 'latest',

    // New in Version 3
    'debug'    => true,
    'retries'  => 5,

What has changed?

To make all of these improvements for V3, we needed to make some backward-incompatible changes. However, the changes from Version 2 to Version 3 are much fewer than the changes from Version 1 to Version 2. In fact, much of the way you use the SDK will remain the same. For example, the following code for writing an item to an Amazon DynamoDB table looks exactly the same in both V2 and V3 of the SDK.

$result = $dynamoDbClient->putItem([
    'TableName' => 'Contacts',
    'Item'      => [
        'FirstName' => ['S' => 'Jeremy'],
        'LastName'  => ['S' => 'Lindblom'],
        'Birthday'  => ['M' => [
            'Month' => ['N' => '11'],
            'Date'  => ['N' => '24'],

There are two important changes though that you should be aware of upfront:

  1. V3 requires PHP 5.5 or higher and requires the use of Guzzle 5.
  2. You must now specify the API version (via the "version" client option) when you instantiate a client. This is important, because it allows you to lock-in to the API versions of the services you are using. This helps us and you maintain backward compatibility between future SDK releases, because you will be in charge of API versions you are using. Your code will never be impacted by new service API versions until you update your version setting. If this is not a concern for you, you can default to the latest API version by setting 'version' to 'latest' (this is essentially the default behavior of V2).

What next?

We hope you are excited for Version 3 of the SDK!

We look forward to your feedback as we continue to work towards a stable release. Please reach out to us in the comments, on GitHub, or via Twitter (@awsforphp). We plan to publish more blog posts in the near future to explain some of the new features in more detail. We have already published the API docs for V3, but we’ll be working on improving all the documentation for V3, including creating detailed migration and user guides. We’ll also be speaking about V3 in our session at AWS re:Invent.

We will continue updating and making regular releases for V2 on the "master" branch of the SDK’s GitHub repository. Our work on V3 will happen on a separate "v3" branch until we are ready for a stable release.

Version 3 can be installed via Composer using version 3.0.0-beta.1, or you can download the aws.phar or on GitHub.

Keeping Up with the Latest Release

by Jeremy Lindblom | on | in PHP | Permalink | Comments |  Share

In the past, we’ve used various means to announce new releases of the AWS SDK
for PHP. We’ve recently evaluated our options to decide which tools work best
with our release process, and are easiest for our users to consume.

The best way to track releases of the SDK is to use the "Releases" page of
our GitHub repo
. This page show links to all of the releases, and if you
navigate to a specific releases page, you can see the excerpt of the CHANGELOG
for that release, and download the aws.phar and GitHub allows you
to link directly to the latest release (i.e., and also provides a
Releases atom feed which gets updated each time we tag a release.

We also recommend that you follow @awsforphp on Twitter. We use this
account to make announcements about new releases, blog posts, etc., and often
tweet and retweet other things related to AWS and PHP. We also occasionally like
to ask questions, answer questions, and post tips about the AWS SDK for PHP.

Note: If you are currently subscribed to our PEAR channel’s RSS feed, you
should know that we are no longer making updates to the PEAR channel as of 9/15
(see End of Life of PEAR Channel for more details).

So, subscribe to the Releases atom feed and follow us on Twitter to
stay up-to-date with the SDK and make sure you don’t miss out on any new
features or announcements.

End of Life of PEAR Channel

by Michael Dowling | on | in PHP | Permalink | Comments |  Share

There’s been a noticeable wave of popular PHP projects recently announcing that they will no longer support PEAR as an installation method. Because the AWS SDK for PHP provides a PEAR channel, we’ve been very interested in the discussion in the community on PEAR channel support.

PEAR has been one of the many ways to install the AWS SDK for PHP since 2010. While it’s served us well, better alternatives for installing PHP packages are now available (i.e., Composer) and literally all of the PEAR dependencies of the AWS SDK for PHP are no longer providing updates to their PEAR channels.

Symfony and Pirum

Fabien Potencier recently blogged about the "Rise of Composer and the fall of PEAR", stating that he would soon no longer update the PEAR channels for the packages he maintains (e.g., Symfony, Twig, Swiftmailer, etc.):

I've been using PEAR as a package manager since my first PHP project back
in 2004. I even wrote a popular PEAR channel server,
Pirum ( But today, it's time for me to move
on and announce my plan about the PEAR channels I'm managing.

One of the projects that we rely on to build the PEAR channel for the AWS SDK for PHP is Pirum, and it has made building a PEAR channel slightly less cumbersome. That said, we’ve had to make small modifications to Pirum over the years to suit our needs. With the announcement that Pirum is no longer maintained, we now have much less confidence in relying on it as a tool used to power one of our installation methods.

One of the Symfony project’s Fabien published to a PEAR channel was the Symfony EventDispatcher. The AWS SDK for PHP has a PEAR dependency on the EventDispatcher PEAR channel. Because the channel is no longer updated, users of the SDK via PEAR will not receive any bugfix updates to the EventDispatcher.


PHPUnit, the most popular unit testing framework for PHP applications, recently stopped updating their PEAR channels:

We are taking the next step in retiring the PEAR installation method with
today's release of PHPUnit 3.7.35 and PHPUnit 4.0.17. These two releases
are the last versions of PHPUnit released as PEAR packages. Installing
them using the PEAR Installer will trigger a deprecation message on every
execution of the commandline test runner.

PHPUnit is the testing framework used to test the AWS SDK for PHP.


Guzzle, another dependency of the AWS SDK for PHP’s PEAR channel, is no longer providing updates to their PEAR channel since the 3.9.0 release.

AWS SDK for PHP PEAR Channel

With all of these contributing factors, we will no longer be providing updates to the AWS SDK for PHP PEAR channel starting on Monday, September 15th, 2014. Our PEAR channel will still be available to download older versions of the SDK, but it will not receive any further updates after this date.

If you are currently using the PEAR channel to install the SDK or build downstream packages (e.g., RPMs), please begin to update your installation mechanism to one of the following alternatives:

  1. Composer (the recommended method).
  2. Our zip package that contains all of the dependencies and autoloader. Available at
  3. Our phar file that contains all of the dependencies and sets up an autoloader. Available at

To stay up to date with important fixes and updates, we strongly recommend migrating to one of the installation methods listed above.

More instructions on installing the AWS SDK for PHP can be found in the user guide.

Release: AWS SDK for PHP – Version 2.6.12

by Jeremy Lindblom | on | in PHP | Permalink | Comments |  Share

We would like to announce the release of version 2.6.12 of the AWS SDK for PHP. This release adds support for new regions to the Kinesis client and new features to the AWS Support and AWS IAM clients.

Install the SDK

Release: AWS SDK for PHP – Version 2.6.11

by Michael Dowling | on | in PHP | Permalink | Comments |  Share

We would like to announce the release of version 2.6.11 of the AWS SDK for PHP.

  • Added support for Amazon Cognito Identity
  • Added support for Amazon Cognito Sync
  • Added support for Amazon CloudWatch Logs
  • Added support for editing existing health checks and associating health checks with tags to the Amazon Route 53 client
  • Added the ModifySubnetAttribute operation to the Amazon EC2 client

Install the SDK

Release: AWS SDK for PHP – Version 2.6.10

by Jeremy Lindblom | on | in PHP | Permalink | Comments |  Share

We would like to announce the release of version 2.6.10 of the AWS SDK for PHP. This release adds support for new regions to the AWS CloudTrail and Amazon Kinesis clients.

Install the SDK

Release: AWS SDK for PHP – Version 2.6.9

by Jeremy Lindblom | on | in PHP | Permalink | Comments |  Share

We would like to announce the release of version 2.6.9 of the AWS SDK for PHP. This release adds support for uploading document batches and submitting search and suggestion requests to an Amazon CloudSearch domain using the new CloudSearch Domain client. It also adds support for configuring delivery notifications to the Amazon SES client, and updates the Amazon CloudFront client to work with the latest API version.

  • Added support for the CloudSearchDomain client, which allows you to search and upload documents to your CloudSearch domains.
  • Added support for delivery notifications to the Amazon SES client.
  • Updated the CloudFront client to support the 2014-05-31 API.
  • Merged PR #316 as a better solution for issue #309.

Install the SDK

Release: AWS SDK for PHP – Version 2.6.8

by Jeremy Lindblom | on | in PHP | Permalink | Comments |  Share

We would like to announce the release of version 2.6.8 of the AWS SDK for PHP. This release updates the Amazon Elastic Transcoder and Amazon EMR clients to use the latest service descriptions, and fixes a few issues.

  • Added support for closed captions to the Elastic Transcoder client.
  • Added support for IAM roles to the Elastic MapReduce client.
  • Updated the S3 PostObject to ease customization.
  • Fixed an issue in some EC2 waiters by merging PR #306.
  • Fixed an issue with the DynamoDB WriteRequestBatch by merging PR #310.
  • Fixed issue #309, where the url_stat() logic in the S3 Stream Wrapper was affected by a change in the latest versions of PHP. If you are running version 5.4.29+, 5.5.13+, or 5.6.0+ of PHP, and you are using the S3 Stream Wrapper, you need to update your SDK in order to prevent runtime errors.

We also released version 2.6.7 last week, but forgot to mention it on the blog. Here are the changes from 2.6.7:

  • Added support for Amazon S3 server-side encryption using customer-provided encryption keys.
  • Updated the Amazon SNS client to support message attributes.
  • Updated the Amazon Redshift client to support new cluster parameters.
  • Updated PHPUnit dev dependency to 4.* to work around a PHP serializing bug.

Install the SDK

Guzzle 4 and the AWS SDK

by Jeremy Lindblom | on | in PHP | Permalink | Comments |  Share

Since Guzzle 4 was released in March (and even before then), we’ve received several requests for us to update the AWS SDK for PHP to use Guzzle 4. Earlier this month, we tweeted about it too and received some pretty positive feedback about the idea. We wanted to take some time to talk about what upgrading Guzzle would mean for the SDK and solicit your feedback.

The SDK relies heavily on Guzzle

If you didn’t already know, the AWS SDK for PHP relies quite heavily on version 3 of Guzzle. The AWS service clients extend from the Guzzle service clients, and we have formatted the entire set of AWS APIs into Guzzle "service descriptions". Roughly 80 percent of what the SDK does is done with Guzzle. We say all this because we want you to understand that updating the SDK to use Guzzle 4 is potentially a big change.

What does Guzzle 4 offer?

We’ve had several requests for Guzzle 4 support, and we agree that it would be great. But what exactly does Guzzle 4 offer — besides it being the new "hotness" — that makes it worth the effort?

We could mention a few things about the code itself: it’s cleaner, it’s better designed, and it has simpler and smaller interfaces. While those are certainly good things, they’re not strong enough reasons to change the SDK. However, Guzzle 4 also includes some notable improvements and new features, including:

  • It’s up to 30 percent faster and consumes less memory than Guzzle 3 when sending requests serially.
  • It no longer requires cURL, but still uses cURL by default, if available.
  • It supports swappable HTTP adapters, which enables you to provide custom adapters. For example, this opens up the possibility for a non-blocking, asynchronous adapter using ReactPHP.
  • It has improved cURL support, including faster and easier handling of parallel requests using a rolling queue approach instead of batching.

These updates would provide great benefits to SDK users, and would allow even more flexible and efficient communications with AWS services.

Guzzle 4 has already been adopted by Drupal, Laravel, Goutte, and other projects. I expect it to be adopted by even more during the rest of this year, and as some of the supplementary Guzzle packages reach stable releases. We definitely want users of the AWS SDK for PHP to be able to use the SDK alongside these other packages without causing conflicts or bloat.

Consequences of updating to Guzzle 4

Because the AWS SDK relies so heavily on Guzzle, the changes to Guzzle will require changes to the SDK.

In Guzzle 4, many things have changed. Classes have been renamed or removed, including classes that are used by the current SDK and SDK users. A few notable examples include the removal of the GuzzleBatch and GuzzleIterator namespaces, and how GuzzleHttpEntityBody has been changed and moved to GuzzleHttpStreamStream.

The event system of Guzzle 4 has also changed significantly. Guzzle has moved away from the Symfony Event Dispatcher, and is now using its own event system, which is pretty nice. This affects any event listeners and subscribers you may have written for Guzzle 3 or the SDK, because they will need a little tweaking to work in Guzzle 4.

Another big change in Guzzle 4 is that it requires PHP 5.4 (or higher). Using Guzzle 4 would mean that the SDK would also require PHP 5.4+.

Most of the changes in Guzzle 4 wouldn’t directly affect SDK users, but there are a few, like the ones just mentioned, that might. Because of this, if the SDK adopted Guzzle 4, it would require a new major version of the SDK: a Version 3.

What are your thoughts?

We think that updating the SDK to use Guzzle 4 is the best thing for the SDK and SDK users. Now that you know the benefits and the consequences, we want to hear from you. Do you have any questions or concerns? What other feedback or ideas do you have? Please join our discussion on GitHub or leave a comment below.

AWS at Laracon 2014

by Jeremy Lindblom | on | in PHP | Permalink | Comments |  Share

I recently had the pleasure to attend and speak at Laracon, which is a conference for users of the Laravel PHP framework.

This is the second year that they have done Laracon. Last year, Laracon (US) was in Washington D.C., but this year they did it in New York City. The thing that impressed me most about this conference was how excited everyone was to be there. The Laravel community is very energetic, and they are growing. I definitely felt that energy, and I believe it helped make the event a good experience for all of the attendees.

I was honored to be able to speak to the attendees about Amazon Web Services. My talk was titled AWS for Artisans, and I focused on "The Cloud", AWS in general, and the AWS SDK for PHP. To tie everything together, I walked through the creation of a simple, but scalable, Laravel application, where pictures of funny faces are uploaded and displayed. I showed how the SDK was used and how AWS Elastic Beanstalk and other AWS services fit into the architecture.

Here are some of my favorite moments/comments from the presentation:

And here are the resources from the presentation:

There were already many existing AWS customers at Laracon, and it was nice to be able to talk to them, answer their questions, and hear their feedback and ideas. I also enjoyed talking to the developers that had yet to try AWS. Use the AWS credits I gave you to do something awesome! :-) Thank you to everyone that I had conversations with.