Tag: php


Release: AWS SDK for PHP – Version 2.6.2

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

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

  • Added support for Amazon SQS message attributes.
  • Fixed Amazon S3 multi-part uploads so that manually set ContentType values are not overwritten.
  • No longer recalculating file sizes when an Amazon S3 socket timeout occurs.
  • Added better environment variable detection.

Install the SDK

Release: AWS SDK for PHP – Version 2.6.1

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

We would like to announce the release of version 2.6.1 of the AWS SDK for PHP. This release adds support for the latest features in Amazon DynamoDB, Amazon ElastiCache, and Auto Scaling; introduces support for a new INI-formatted credentials file (more information about this will be coming in a future blog post); and fixes a few issues in the Amazon S3 Stream Wrapper.

Install the SDK

Testing Webhooks Locally for Amazon SNS

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

In a recent post, I talked about Receiving Amazon SNS Messages in PHP. I showed you how to use the SNS Message and MessageValidator classes in the AWS SDK for PHP to handle incoming SNS messages. The PHP code for the webhook is easy to write, but can be difficult to test properly, since it must be deployed to a server in order to be accessible to Amazon SNS. I’ll show you how you can actually test your code locally with the help of a few simple tools.

Testing Tools

To test the code I wrote for the blog post, I used PHP’s built-in web server (available in PHP 5.4 and later) to serve the code locally. I used another tool called ngrok to expose the locally running PHP server to the public internet. Ngrok does this by creating a tunnel to a specified port on your local machine.

You can use PHP’s built-in web server and ngrok on Windows, Linux, and Mac OS X. If you have PHP 5.4+ installed, then the built-in server is ready to use. To install ngrok, use the simple instructions on the ngrok website. I work primarily in OS X, so you may need to modify the commands I use in the rest of this post if you are using another platform.

Setting Up the PHP Code

First, you’ll need the PHP code that will handle the incoming messages. My post about receiving SNS messages provides a complete code example for doing this.

Let’s create a new folder in your home directly to use for this test. We’ll also install Composer, the AWS SDK for PHP, create a directory for the webroot, and create files for the PHP code and a log.

mkdir ~/sns-message-test && cd ~/sns-message-test
curl -sS https://getcomposer.org/installer | php
php composer.phar require aws/aws-sdk-php:~2.6.0
touch messages.log
mkdir web && touch web/index.php

Now take the PHP code from the other blog post and put it in index.php. Here is that same code, but with the require statement needed to load the SDK with our current file structure. I am also going to update the code to log the incoming messages to a file so we can easily see that the messages are being handled correctly.

<?php

require __DIR__ . '/../vendor/autoload.php';

use AwsSnsMessageValidatorMessage;
use AwsSnsMessageValidatorMessageValidator;
use GuzzleHttpClient;

// Make sure the request is POST
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405);
    die;
}

try {
    // Create a message from the post data and validate its signature
    $message = Message::fromRawPostData();
    $validator = new MessageValidator();
    $validator->validate($message);
} catch (Exception $e) {
    // Pretend we're not here if the message is invalid
    http_response_code(404);
    die;
}

if ($message->get('Type') === 'SubscriptionConfirmation') {
    // Send a request to the SubscribeURL to complete subscription
    (new Client)->get($message->get('SubscribeURL'))->send();
}

// Log the message
$file = new SplFileObject(__DIR__ . '/../messages.log', 'a');
$file->fwrite($message->get('Type') . ': ' . $message->get('Message') . "n");

Creating an Amazon SNS Topic

Before you can perform any tests, you must set up an Amazon SNS topic. You can do this easily in the AWS Management Console by following the Getting Started with Amazon Simple Notification Service guide. This guide also shows how to subscribe to a topic and publish a message, which you will also need to do in a moment.

Setting Up the Server

OK, we have an Amazon SNS topic ready and all of the files we need in place. Now we need to start up the server and make it accessible to Amazon SNS. To do this, create 3 separate terminal windows or tabs, which we will use for 3 separate long-running processes: the server, ngrok, and tailing the messages log.

Launching the PHP Built-in Server

In the first terminal window, use the following command to start up the PHP built-in web server to serve our little test webhook. (Note: you can use a different port number, just make sure you use the same one with ngrok.)

php -S 127.0.0.1:8000 -t web/

This will create some output that looks something like the following:

PHP 5.4.24 Development Server started at Mon Mar 31 11:02:14 2014
Listening on http://127.0.0.1:8000
Document root is /Users/your-user/sns-message-test/web
Press Ctrl-C to quit.

If you access http://127.0.0.1:8000 from your web browser, you will likely see a blank page, but that request will show up in this terminal window. Since our code is set up to respond only to POST requests, we will see the expected behavior of a 405 HTTP code in the response.

[Mon Mar 31 11:02:44 2014] 127.0.0.1:61409 [405]: /

Creating a Tunnel with ngrok

In the second terminal window, use the following command to create an ngrok tunnel to the PHP server. Use the same port as you did in the previous section.

ngrok 8000

That was easy! The output of this command will contain a publicly accessible URL that forwards to your localhost.

Tunnel Status                 online
Version                       1.6/1.5
Forwarding                    http://58565ed9.ngrok.com -> 127.0.0.1:8000
Forwarding                    https://58565ed9.ngrok.com -> 127.0.0.1:8000
Web Interface                 127.0.0.1:4040
# Conn                        1
Avg Conn Time                 36.06ms

ngrok also provides a small web app running on localhost:4040 that displays all of the incoming requests through the tunnel. It also allows you to click a button to replay a request, which is really helpful for testing and debugging your webhooks.

Tailing the Message Logs

Let’s use the third terminal window to tail the log file that our PHP code writes the incoming messages to.

tail -f messages.log

This won’t show anything yet, but once we start publishing Amazon SNS messages to our topic, they should be printed out in this window.

Testing the Incoming SNS Messages

Now that everything is running and wired up, head back to the Amazon SNS console and subscribe the URL provided by ngrok as an HTTP endpoint for your SNS topic.

If all goes well, you should see output similar to the following on each of the 3 terminal windows.

PHP Server:

[Tue Apr  1 08:51:13 2014] 127.0.0.1:50190 [200]: /

ngrok:

POST /                        200 OK

Log:

SubscriptionConfirmation: You have chosen to subscribe to the topic arn:aws:sns:us-west-2:01234567890:sdk-test. To confirm the subscription, visit the SubscribeURL included in this message.

Back in the SNS console, you should see that the subscription has been confirmed. Next, publish a message to the topic to test that normal messages are processed correctly. The output should be similar:

PHP Server:

[Tue Apr  1 10:08:14 2014] 127.0.0.1:51235 [200]: /

ngrok:

POST /                        200 OK

Log:

Notification: THIS IS MY TEST MESSAGE!

Nice work!

Cleaning Up

Now that we are done, be sure to shutdown (Ctrl+C) ngrok, tail, and the local php server. Unsubscribe the defunct endpoint you used for this test, or just delete the SNS topic entirely if you aren’t using it for anything else.

With these tools, you can now test webhooks in your applications locally and interact with Amazon SNS more easily.

Receiving Amazon SNS Messages in PHP

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

The following post details how to use version 2 of the AWS SDK for PHP to receive and validate HTTP(S) messages from Amazon SNS. For a guide on how to do so with version 3 of the SDK, please see our updated post.

Handling inbound Amazon SNS notification messages with PHP is simple. In this post, I’ll show you how to retrieve data from incoming messages, and verify that the messages are coming from Amazon SNS.

A Little About Amazon SNS

Amazon Simple Notification Service (Amazon SNS) is a fast, fully-managed, push messaging service. Amazon SNS can deliver messages to email, mobile devices (i.e., SMS; iOS, Android and FireOS push notifications), Amazon SQS queues, and HTTP/HTTPS endpoints.

With Amazon SNS, you can setup topics to publish custom messages to subscribed endpoints. However, SNS messages are used by many of the other AWS services to communicate information asynchronously about your AWS resources. Some examples include:

  • Configuring Amazon Glacier to notify you when a retrieval job is complete.
  • Configuring AWS CloudTrail to notify you when a new log file has been written.
  • Configuring Amazon Elastic Transcoder to notify you when a transcoding job changes status (e.g., from "Progressing" to "Complete")

Though you can certainly subscribe your email address to receive SNS messages from service events like these, your inbox would fill up rather quickly. There is great power, however, in being able to subscribe an HTTP/HTTPS endpoint to receive the messages. This allows you to program webhooks for your applications to easily respond to various events.

Receiving a Message

In order for an HTTP/HTTPS endpoint to receive messages, you must subscribe the endpoint to an SNS topic. Before you do that, you need to create and deploy a script to the endpoint to process the messages.

Here is a naïvely simple PHP script that can read a posted SNS message.

<?php

// Fetch the raw POST body containing the message
$postBody = file_get_contents('php://input');

// JSON decode the body to an array of message data
$message = json_decode($postBody, true);
if ($message) {
    // Do something with the data
    echo $message['Message'];
}

The AWS SDK for PHP has an SNS Message class for representing an SNS message. It encapsulates the preceding code, and also validates the structure of the message data.

<?php

// Include Composer autoloader
require 'path/to/vendor/autoload.php';

// Create a message object from the POST body
$message = AwsSnsMessageValidatorMessage::fromRawPostData();
echo $message->get('Message');

Amazon SNS sends different types of messages including SubscriptionConfirmation, Notification, and UnsubscribeConfirmation. The formats of these messages are described on the Appendix: Message and JSON Formats section of the Amazon SNS Developer Guide.

Confirming a Subscription to a Topic

In order to handle a SubscriptionConfirmation message, we need to add some code that actually does something with the message. SubscriptionConfirmation messages provide a URL that you can use to confirm the subscription. We’ll use a Guzzle HTTP client to send a GET request to the URL.

$message = AwsSnsMessageValidatorMessage::fromRawPostData();

// Create a Guzzle client and send a request to the SubscribeURL
$client = new GuzzleHttpClient();
$client->get($message->get('SubscribeURL'))->send();

Verifying a SNS Message’s Signature

Messages from Amazon SNS are signed. It’s a good practice to verify the signature and ensure that a message was actually sent from Amazon SNS before performing actions as a result of the message. The SDK includes a MessageValidator class for validating the message, but you must have the OpenSSL PHP extension installed to use it.

use AwsSnsMessageValidatorMessage;
use AwsSnsMessageValidatorMessageValidator;

$message = Message::fromRawPostData();

// Validate the message
$validator = new MessageValidator();
$validator->validate($message);

Handling Notifications

Let’s put it all together and add some extra code for handling both SubscriptionConfirmation and Notification messages.

<?php

require 'path/to/vendor/autoload.php';

use AwsSnsMessageValidatorMessage;
use AwsSnsMessageValidatorMessageValidator;
use GuzzleHttpClient;

// Make sure the request is POST
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405);
    die;
}

try {
    // Create a message from the post data and validate its signature
    $message = Message::fromRawPostData();
    $validator = new MessageValidator();
    $validator->validate($message);
} catch (Exception $e) {
    // Pretend we're not here if the message is invalid
    http_response_code(404);
    die;
}

if ($message->get('Type') === 'SubscriptionConfirmation') {
    // Send a request to the SubscribeURL to complete subscription
    (new Client)->get($message->get('SubscribeURL'))->send();
} elseif ($message->get('Type') === 'Notification') {
    // Do something with the notification
    save_message_to_database($message);
}

Conclusion

As you can see, receiving, verifying and handling Amazon SNS messages is simple. Setting up your application to receive SNS messages will allow you to create applications that can handle asynchronous communication from AWS services and other parts of your application.

EDIT: My next blog post is a follow up to this one, and describes how you can test your Amazon SNS webhooks locally.

Release: AWS SDK for PHP – Version 2.6.0

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

We would like to announce the release of version 2.6.0 of the AWS SDK for PHP. This release updates the Amazon CloudSearch, Amazon EC2, and Amazon Redshift clients to support their newest APIs and features. See the CHANGELOG for a full list of changes.

Version 2.6.0 is a major release of the SDK, and contains some backwards-incompatible changes. These changes only effect the usage of the Amazon CloudSearch client. See the UPGRADING.md document for more details.

Install the SDK

Release: AWS SDK for PHP – Version 2.5.4

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

We would like to announce the release of version 2.5.4 of the AWS SDK for PHP. This release updates the Amazon CloudFront client, AWS OpsWorks client, and Elastic Load Balancing client; adds support for the AWS_SECRET_ACCESS_KEY environment variable; updates the Amazon S3 stream wrapper; addresses an issue with dot-segments in the Amazon S3 directory sync, and addresses an issue with Amazon S3 pre-signed URLs. Please refer to the CHANGELOG for a complete list of changes.

Install the SDK

Release: AWS SDK for PHP – Version 2.5.3

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

We would like to announce the release of version 2.5.3 of the AWS SDK for PHP. This release provides several client updates, Amazon S3 client issue fixes, and additional iterators. Please refer to the CHANGELOG for a complete list of changes.

Install the SDK

AWS at PHP Conferences in Spring 2014

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

This spring, I’ll be traveling to Dallas and New York City to represent the AWS SDK for PHP team and be with fellow PHP developers. I hope to see you too!

In late April, I’ll be going to Dallas for Lone Star PHP! I have two talks that I’ll be sharing there: Recursion: Making Big Problems Smaller and Surviving and Thriving in Technical Interviews. I will not be speaking specifically about AWS or the AWS SDK for PHP at Lone Star, but if you want to chat with me about AWS, then definitely come find me. Looking at the other speakers that are going to be there, I can tell this will be a really great conference.

I have another great opportunity in May to speak at Laracon in New York City, a conference for developers (i.e., "artisans") using the Laravel Framework. My talk is titled AWS for Artisans, and I’ll be talking about the services that AWS provides and the ways Laravel artisans can use AWS. I’ll also showcase some of the integrations that exist between the Laravel Framework and the AWS SDK for PHP, including the AWS Service Provider for Laravel 4 and the Laravel Queue component’s Amazon SQS driver.

I look forward to meeting new people and seeing old friends at both of these conferences. Make sure to come introduce yourself if you see me there. If you haven’t bought tickets for either of these events yet, there is still time. Do it!

Using New Regions and Endpoints

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

Last week, a customer asked us how they could configure the AWS SDK for PHP to use Amazon SES with the EU (Ireland) Region. SES had just released support for the EU Region, but there was no tagged version of the SDK that supported it yet.

Our typical process is to push new support for regions to the master branch of the AWS SDK for PHP repository as soon as possible after they are announced. In fact, at the time that the customer asked us about EU Region support in SES, we had already pushed out support for it. However, if you are using only tagged versions of the SDK, which you should do with production code, then you may have to wait 1 or 2 weeks until a new version of the SDK is released.

Configuring the base URL of your client

Fortunately, there is a way to use new regions and endpoints, even if the SDK does not yet support a new region for a service. You can manually configure the base_url of a client when you instantiate it. For example, to configure an SES client to use the EU Region, do the following:

$ses = AwsSesSesClient::factory(array(
    'key'      => 'YOUR_AWS_ACCESS_KEY_ID',
    'secret'   => 'YOUR_AWS_SECRET_KEY',
    'region'   => 'eu-west-1',
    'base_url' => 'https://email.eu-west-1.amazonaws.com',
));

Remember, you only need to specify the base_url if the SDK doesn’t already support the region. For regions that the SDK does support, the endpoint is automatically determined.

To find the correct URL to use for your desired service and region, see the Regions and Endpoints page of the AWS General Reference documentation.

Using the base_url for other reasons

The base_url option can be used for more than just accessing new regions. It can be used to allow the SDK to send requests to any endpoint compatible with the API of the service you are using (e.g., mock/test services, private beta endpoints).

An example of this is the DynamoDB Local tool that acts as a small client-side database and server that mimics Amazon DynamoDB. You can easily configure a DynamoDB client to work with DynamoDB Local by using the base_url option (assuming you have correctly installed and started DynamoDB Local).

$dynamodb = AwsDynamoDbDynamoDbClient::factory(array(
    'key'      => 'YOUR_AWS_ACCESS_KEY_ID',
    'secret'   => 'YOUR_AWS_SECRET_KEY',
    'region'   => 'us-east-1',
    'base_url' => 'http://localhost:8000',
));

For more information, see Setting a custom endpoint in the AWS SDK for PHP User Guide.

Using the latest SDK via Composer

If you are using Composer with the SDK, then you have another option for picking up new features, like newly supported regions, without modifying your code. If you need to use a new feature or bugfix that is not yet in a tagged release, you can do so by adjusting the SDK dependency in your composer.json file to use our development alias 2.5.x-dev.

{
    "require": {
        "aws/aws-sdk-php": "2.5.x-dev"
    }
}

Using the development alias, instead of dev-master, is ideal, because if you have other dependencies that require the SDK, version constraints like "2.5.*" will still resolve correctly. Remember that relying on a non-tagged version of the SDK is not recommended for production code.

Release: AWS SDK for PHP – Version 2.5.2

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

We would like to announce the release of version 2.5.2 of the AWS SDK for PHP. This release adds support for dead letter queues to the Amazon Simple Queue Service client. Please see the official release notes or the release CHANGELOG for a complete list of changes.

Install the SDK