Mastering the AWS SDK for PHP (TLS306) | AWS re:Invent 2013

31,678 views

Published on

The AWS SDK for PHP allows PHP developers to interact with AWS services in a fluid and familiar way. Learn how to use convenience features, like iterators and waiters, as well as high-level abstractions, such as the Amazon Simple Storage Service (Amazon S3) stream wrapper. We also demonstrate the powerful capabilities inherited from the underlying Guzzle library.

Published in: Technology
1 Comment
9 Likes
Statistics
Notes
No Downloads
Views
Total views
31,678
On SlideShare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
140
Comments
1
Likes
9
Embeds 0
No embeds

No notes for slide

Mastering the AWS SDK for PHP (TLS306) | AWS re:Invent 2013

  1. 1. Mastering the AWS SDK for PHP Michael Dowling & Jeremy Lindblom, AWS Developer Resources November 15, 2013 © 2013 Amazon.com, Inc. and its affiliates. All rights reserved. May not be copied, modified, or distributed in whole or in part without the express consent of Amazon.com, Inc.
  2. 2. PART 1 Using the AWS SDK for PHP by working with PART 2 Amazon S3 High-level features for common use cases with the AWS SDK for PHP
  3. 3. @awsforphp Follow Us! AWS SDK for PHP https://github.com/aws/aws-sdk-php
  4. 4. AWS SDK for PHP • Suite of HTTP clients for AWS services • Built on top of Guzzle (guzzlephp.org) – Persistent connections, parallel requests – Event hooks, plugins, wire logging • Helpful functionality – – – – Easy pagination "waiters" Automatic retries etc.
  5. 5. AWS SDK for PHP – Installing • • • • • Composer / Packagist Phar Zip PEAR Yum (Amazon Linux)
  6. 6. AWS SDK for PHP – Installing via Composer In your composer.json: { "require": { "aws/aws-sdk-php": "~2.4" } } From your terminal: > composer.phar install http://getcomposer.org
  7. 7. PART 1 Using the AWS SDK for PHP
  8. 8. Using the AWS SDK for PHP  CreateBucket  PutObject  ListObjects Amazon S3 operations
  9. 9. Amazon Simple Storage Service (Amazon S3) Scalable storage in the cloud http://my-stuff.s3.amazonaws.com/photos/kittens.jpg Bucket Name Object Key
  10. 10. Using the AWS SDK for PHP  CreateBucket  PutObject  ListObjects 
  11. 11. Creating a Bucket – Complete Example <?php require 'vendor/autoload.php'; use AwsCommonAws; use AwsS3ExceptionS3Exception; $aws = Aws::factory('config.php'); $s3 = $aws->get('s3'); try { $result = $s3->createBucket([ 'Bucket' => 'bucket-name', ]); $s3->waitUntilBucketExists([ 'Bucket' => 'bucket-name', ]); } catch (S3Exception $e) { echo $e->getMessage(); }
  12. 12. Two Ways to Instantiate a Service Client 1. Client factory method 2. Service builder (AwsCommonAws)
  13. 13. Instantiate a Client via its Factory Method use AwsS3S3Client; $s3 = S3Client::factory([ 'key' => '{your-aws-access-key-id}', 'secret' => '{your-aws-secret-key}', // 'region' => 'us-east-1', ]);
  14. 14. Instantiate a Client via the Service Builder <?php require 'vendor/autoload.php'; use AwsCommonAws; $aws = Aws::factory('/path/to/config.php'); $s3 = $aws->get('s3'); $s3again = $aws->get('s3'); var_dump($s3 === $s3again); #> bool(true)
  15. 15. Providing Credentials • Options array ['key' => '?', 'secret' => '?'] • Configuration file • Environment credentials – AWS_ACCESS_KEY_ID – AWS_SECRET_KEY • IAM Instance Profile credentials See http://blogs.aws.amazon.com/php (Providing credentials to the AWS SDK for PHP)
  16. 16. Executing a Command try { $result = $s3->createBucket([ 'Bucket' => $bucket, ]); } catch (AwsS3ExceptionS3Exception $e) { echo $e->getMessage(); }
  17. 17. Executing a Command – API Docs
  18. 18. Handling a Response – Modeled Responses $result = $s3->listBuckets(); $result['Buckets']; // Implements ArrayAccess print_r($result->toArray()); echo $result; $result->getPath('Buckets/0/Name'); $result->getPath('Buckets/*/Name');
  19. 19. Handling a Response – API Docs
  20. 20. Wire Logging – Debug Easily <?php require 'vendor/autoload.php'; use AwsCommonAws; use AwsS3ExceptionS3Exception; use GuzzlePluginLogLogPlugin; $aws = Aws::factory('config.php'); $s3 = $aws->get('s3'); $log = LogPlugin::getDebugPlugin(); $s3->addSubscriber($log); try { $result = $s3->createBucket([ 'Bucket' => 'bucket-name', ]); $s3->waitUntilBucketExists([ 'Bucket' => 'bucket-name', ]); } catch (S3Exception $e) { echo $e->getMessage(); }
  21. 21. Wire Logging – Output # Request: PUT / HTTP/1.1 Host: this-is-my-test-wonderful-bucket.s3.amazonaws.com User-Agent: aws-sdk-php2/2.4.6 Guzzle/3.7.3 curl/7.25.0 PHP/5.3.27 Date: Wed, 25 Sep 2013 23:03:13 +0000 Authorization: AWS AKIAEXAMPLEEXAMPLE:Xn2lJPREXAMPLEQkPmY0IAUng= Content-Length: 0 # Response: HTTP/1.1 200 OK x-amz-id-2: eNUZEXAMPLEM4U7c/4WPIlshkfVUEXAMPLEUkyKirVgjEXAMPLEsfwZ3Mx x-amz-request-id: C91E6E8CD19680F7 Date: Wed, 25 Sep 2013 23:03:15 GMT Location: /this-is-my-test-wonderful-bucket
  22. 22. Plugins • Plugin architecture from Guzzle • Uses the Symfony Event Dispatcher • Many plugins included with Guzzle (Log, Backoff, History, Mock, HTTP Cache, etc.)
  23. 23. Wait for it… <?php require 'vendor/autoload.php'; use AwsCommonAws; use AwsS3ExceptionS3Exception; $aws = Aws::factory('config.php'); $s3 = $aws->get('s3'); try { $result = $s3->createBucket([ 'Bucket' => 'bucket-name', ]); $s3->waitUntilBucketExists([ 'Bucket' => 'bucket-name', ]); } catch (S3Exception $e) { echo $e->getMessage(); }
  24. 24. Waiters $result = $s3->createBucket([ 'Bucket' => $bucket ]); $s3->waitUntilBucketExists([ 'Bucket' => $bucket ]); • Poll resources until available • Handle asynchronous and eventually consistent operations more easily
  25. 25. Using the AWS SDK for PHP  CreateBucket  PutObject   ListObjects
  26. 26. Uploading an Object to Amazon S3 $result = $s3->putObject([ 'Bucket' => 'my-cool-photos', 'Key' => 'photos/photo01.jpg', 'Body' => fopen('/path/to/photo01.jpg', 'r'), 'ACL' => 'public-read', ]); $url = $result->get('ObjectURL');
  27. 27. Command Syntax – Short vs. Long Form // Short form $result = $s3->putObject([ // ... ]); // Long form $command = $s3->getCommand('PutObject', [ // ... ]); $result = $command->getResult();
  28. 28. Executing Commands in Parallel $command1 = $s3->getCommand('PutObject', [ 'Bucket' => 'my-bucket-name', 'Key' => 'my-first-key', 'Body' => fopen('path/to/file1.ext', 'r') ]); $command2 = $s3->getCommand('PutObject', [ 'Bucket' => 'my-bucket-name', 'Key' => 'my-second-key', 'Body' => fopen('path/to/file2.ext', 'r') ]); $s3->execute([$command1, $command2]);
  29. 29. Using the AWS SDK for PHP  CreateBucket  PutObject  ListObjects 
  30. 30. Listing Objects in Your Bucket $result = $s3->listObjects([ 'Bucket' => 'my-bucket-name', ]); $nextResult = $s3->listObjects([ 'Bucket' => 'my-bucket-name', 'Marker' => 'photos/photo-1000.jpg', ]);
  31. 31. Iterators – Enumerate Your Data Easily • Iterate through entire result sets • No handling of markers or tokens • Lazy loads results • Compatible with SPL iterators
  32. 32. Iterators – Enumerating Your Data Easily $objects = $s3->getListObjectsIterator([ 'Bucket' => 'my-bucket-name', ]); foreach ($objects as $object) { echo $object['Key'] . "n"; }
  33. 33. SDK 1.x – A Time Before Iterators $sk = null; $people = array(); do { $params = array('TableName'=>'people'); if ($sk) { $params['ExclusiveStartKey'] = array( 'HashKeyElement' => array( 'S' => $sk ) ); $sk= null; } $r = $dynamo_db->scan($params); if ($r->isOK()) { foreach ($r->body->Items as $item) { echo (string) $item->name->S; } if ($lk = $r->body->LastEvaluatedKey) { $sk = (string) $lk->HashKeyElement->S; } } else { throw new DynamoDB_Exception('...'); } } while ($sk);
  34. 34. SDK 1.x – A Time Before Iterators $sk = null; $people = array(); do { $params = array('TableName'=>'people'); if ($sk) { $params['ExclusiveStartKey'] = array( 'HashKeyElement' => array( 'S' => $sk ) ); $sk= null; } $r = $dynamo_db->scan($params); if ($r->isOK()) { foreach ($r->body->Items as $item) { echo (string) $item->name->S; } if ($lk = $r->body->LastEvaluatedKey) { $sk = (string) $lk->HashKeyElement->S; } } else { throw new DynamoDB_Exception('...'); } } while ($sk);
  35. 35. SDK 2.x – The Era of Iterators $scan = $db->getScanIterator([ 'TableName' => 'People', 'AttributesToGet' => ['Id', 'Name'] ]); foreach ($scan as $person) { echo $item['Name']['S']; }
  36. 36. Advanced Iterator Usage – Example $objects = $s3->getListObjectsIterator([ 'Bucket' => 'my-bucket-name', ]); $objects = new LimitIterator($objects, 0, 5); foreach ($objects as $object) { echo $object['Key'] . "n"; }
  37. 37. Using the AWS SDK for PHP  CreateBucket  PutObject  ListObjects
  38. 38. PART 2 High-level Abstractions in the AWS SDK for PHP
  39. 39. "I want to use Amazon S3 like a local filesystem." Amazon S3 Stream Wrapper
  40. 40. PHP Stream Wrappers • Provide a consistent I/O interface for various protocols – fopen(), fread(), file_get_contents() , mkdir(), etc… – file://, http://, ftp://, php://, …
  41. 41. PHP Stream Wrapper Protocols echo file_get_contents('/path/to/file'); Is equivalent to… echo file_get_contents('file:///path/to/file'); file:// is the protocol
  42. 42. PHP Stream Wrapper Protocols echo file_get_contents('http://www.amazon.com'); http:// is the protocol
  43. 43. Amazon S3 Stream Wrapper // First, register the wrapper $s3 = AwsS3S3Client::factory(); $s3->registerStreamWrapper(); echo file_get_contents('s3://bucket_name/key'); file_put_contents('s3://bucket_name/key', 'hi!'); s3:// bucket_name /key
  44. 44. Pseudo-directory • Amazon S3 knows about buckets and keys • There aren't real subdirectories • Pseudo-directories can be created using a key prefix Bucket: foo Key: baz/bar/bam URL: http://foo.s3.amazonaws.com/baz/bar/bam
  45. 45. Reading bytes off of a stream $fp = fopen('s3://bucket_name/key', 'r'); while (!feof($fp)) { echo fread($fp, 1024); } fclose($fp); Instead of reading all bytes up front and then using them
  46. 46. Using Stream Filters Filters are used for: Conversion, Compression, Encryption, etc. $in = fopen('s3://bucket_name/key.zip', 'r'); $out = fopen('/path/to/file', 'w'); stream_filter_append($out, 'zlib.inflate'); stream_copy_to_stream($in, $out); fclose($in); fclose($out);
  47. 47. Listing Objects and Buckets $dir = "s3://bucket_name/"; if (is_dir($dir) && ($dh = opendir($dir))) { while (($file = readdir($dh)) !== false) { echo "Name: {$file}n"; } closedir($dh); }
  48. 48. Listing Objects and Buckets The more intuitive recursive iterator iterator iterator iterator … $dir = 's3://bucket_name'; $iterator = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($dir), RecursiveIteratorIterator::CHILD_FIRST ); foreach ($iterator as $file) { echo $file->getType() . ': ' . $file . "n"; }
  49. 49. Listing Objects and Buckets file: s3://bucket/aws_logo.png file: s3://bucket/background.gif file: s3://bucket/channel.xml file: s3://bucket/data.txt file: s3://bucket/destruct dir: s3://bucket/dirupload file: s3://bucket/dirupload/aws-autoloader.php file: s3://bucket/dirupload/aws.zip file: s3://bucket/dirupload/guzzle/guzzle/.gitignore file: s3://bucket/dirupload/guzzle/guzzle/.travis.yml file: s3://bucket/dirupload/guzzle/guzzle/CHANGELOG.md file: s3://bucket/dirupload/guzzle/guzzle/LICENSE
  50. 50. PHP Stream Wrappers: Summary • • • • Access Amazon S3 like a local filesystem Read bytes off of a stream on demand Use familiar methods like file_get_contents Access to PHP's stream filters
  51. 51. "I need to upload a local directory to an Amazon S3 bucket" For static blogs, websites, etc.
  52. 52. Local filesystem . ├── images │ ├── dotted-border.png │ ├── email.png │ ├── noise.png │ ├── rss.png │ └── search.png ├── index.html Amazon S3 Bucket . ├── images │ ├── dotted-border.png │ ├── email.png │ ├── noise.png │ ├── rss.png │ └── search.png ├── index.html
  53. 53. uploadDirectory() 1. Recursively iterates over all local files 2. Checks if the file does not exist or if it has changed 3. Uploads matching files (single or multipart) $client->uploadDirectory('/local/directory', 'bucket'); public function uploadDirectory( $directory, $bucket, $keyPrefix = null, array $options = array() )
  54. 54. Key Prefix? https://bucket.s3.amazonaws.com/blogs/index.html $client->uploadDirectory( '/local/dir', 'bucket', 'blogs/' //  Key prefix );
  55. 55. uploadDirectory() Options $client->uploadDirectory('/local/dir', 'bucket', '', [ 'params' => ['ACL' => 'public-read'], 'concurrency' => 20, 'debug' => true ]); Debug output: Uploading /local/dir/images/email.png -> images/email.png (8 bytes) Uploading /local/dir/images/noise.png -> images/noise.png (12 bytes) Uploading /local/dir/images/rss.png -> images/rss.png (100 bytes) Uploading /local/dir/images/search.png -> images/search.png (200 bytes) Uploading /local/dir/index.html -> index.html (1024 bytes)
  56. 56. "I need to download an Amazon S3 bucket to my local filesystem"
  57. 57. downloadBucket() Works exactly like uploadDirectory() $client->downloadBucket ('/local/directory', 'bucket'); public function downloadBucket( $directory, $bucket, $keyPrefix = null, array $options = array() )
  58. 58. Sync Amazon S3 -> Amazon S3 Upload the contents of one Amazon S3 bucket to another using uploadDirectory(). $client->uploadDirectory( 's3://bucket_src', 'bucket_dest' );
  59. 59. "I need to use the SDK with my framework."
  60. 60. Third-party Integrations • Laravel 4 Service Provider • Zend Framework 2 Module • Silex Service Provider https://github.com/aws If you'd like to help us or contribute to another framework integration, please come talk to us.
  61. 61. Mastering the AWS SDK for PHP  Learned how to use the AWS SDK for PHP by working with some basic Amazon S3 operations.  Learned how to speed up some common development use cases by using some of the SDK's high-level abstractions.
  62. 62. What you will do next • Star ★ the AWS SDK for PHP GitHub repo https://github.com/aws/aws-sdk-php • composer install the SDK into your project https://packagist.org/packages/aws/aws-sdk-php • Subscribe to the AWS PHP Development Blog http://blogs.aws.amazon.com/php • Build cool PHP apps on the AWS cloud!
  63. 63. Mastering the AWS SDK for PHP Please give us your feedback on this presentation TLS306 As a thank you, we will select prize winners daily for completed surveys! Follow us: @awsforphp

×