Slide 1

Slide 1 text

Getting Good with the! AWS SDK for PHP!

Slide 2

Slide 2 text

Hi there! I'm Jeremy! •  PHP So"ware Engineer at! •  Co-author of the AWS SDK for PHP! •  Co-organizer of the Seattle PHP User Group! •  @jeremeamia on and | webjeremy.com! •  I like making funny faces!

Slide 3

Slide 3 text

Amazon Web Services o#ers a complete set of infrastructure and application services that enable you to run virtually everything in the cloud.!

Slide 4

Slide 4 text

In other words…! AWS is a bunch of building blocks.!

Slide 5

Slide 5 text

Some of these blocks are for! building your infrastructure,! Amazon Elastic Compute Cloud! (EC2)! Amazon Relational Database Service! (RDS)! Amazon! Route 53!

Slide 6

Slide 6 text

Some of these blocks are for! building your application,! Amazon Simple Storage Service! (S3)! Amazon Simple Queue Service! (SQS)! Amazon Simple Email Service! (SES)!

Slide 7

Slide 7 text

And some of these blocks build on each! other to create more complete solutions.! AWS CloudFormation! AWS! Elastic Beanstalk! AWS! OpsWorks!

Slide 8

Slide 8 text

These building blocks enable you to! do virtually anything in the cloud, like…! Streaming movies to millions of users around the world,! Allowing millions people to quickly share things online with friends,! Processing, storing, and distributing images from Mars.!

Slide 9

Slide 9 text

Hundreds of Thousands of Customers in 190 Countries!

Slide 10

Slide 10 text

Amazon S3! Amazon SES! Amazon SimpleDB! Amazon SNS! Amazon SQS! Amazon SWF! Amazon VPC! Auto Scaling! AWS CloudHSM! AWS Data Pipeline! AWS Elastic Beanstalk! AWS Import/Export! AWS OpsWorks! AWS Marketplace! AWS Storage Gateway! AWS Support! Elastic Load Balancing! Amazon CloudFormation! Amazon CloudFront! Amazon CloudSearch! Amazon CloudWatch! Amazon Direct Connect! Amazon DynamoDB! Amazon EBS! Amazon EC2! Amazon ElastiCache! Amazon Elastic Transcoder! Amazon EMR! Amazon Glacier! Amazon IAM! Amazon Mechanical Turk! Amazon RDS! Amazon Redshi"! Amazon Route53!

Slide 11

Slide 11 text

Amazon S3! Amazon SES! Amazon SimpleDB! Amazon SNS! Amazon SQS! Amazon SWF! Amazon VPC! Auto Scaling! AWS CloudHSM! AWS Data Pipeline! AWS Elastic Beanstalk! AWS Import/Export! AWS OpsWorks! AWS Marketplace! AWS Storage Gateway! AWS Support! Elastic Load Balancing! Amazon CloudFormation! Amazon CloudFront! Amazon CloudSearch! Amazon CloudWatch! Amazon Direct Connect! Amazon DynamoDB! Amazon EBS! Amazon EC2! Amazon ElastiCache! Amazon Elastic Transcoder! Amazon EMR! Amazon Glacier! Amazon IAM! Amazon Mechanical Turk! Amazon RDS! Amazon Redshi"! Amazon Route53! Compute & Networking! Storage & Content Delivery! Databases! Application Services! Deployment & Management!

Slide 12

Slide 12 text

Amazon S3! Amazon SES! Amazon SimpleDB! Amazon SNS! Amazon SQS! Amazon SWF! Amazon VPC! Auto Scaling! AWS CloudHSM! AWS Data Pipeline! AWS Elastic Beanstalk! AWS Import/Export! AWS OpsWorks! AWS Marketplace! AWS Storage Gateway! AWS Support! Elastic Load Balancing! Amazon CloudFormation! Amazon CloudFront! Amazon CloudSearch! Amazon CloudWatch! Amazon Direct Connect! Amazon DynamoDB! Amazon EBS! Amazon EC2! Amazon ElastiCache! Amazon Elastic Transcoder! Amazon EMR! Amazon Glacier! Amazon IAM! Amazon Mechanical Turk! Amazon RDS! Amazon Redshi"! Amazon Route53! 8 services! less than! a year old!

Slide 13

Slide 13 text

Amazon S3! Amazon SES! Amazon SimpleDB! Amazon SNS! Amazon SQS! Amazon SWF! Amazon VPC! Auto Scaling! AWS CloudHSM! AWS Data Pipeline! AWS Elastic Beanstalk! AWS Import/Export! AWS OpsWorks! AWS Marketplace! AWS Storage Gateway! AWS Support! Elastic Load Balancing! Amazon CloudFormation! Amazon CloudFront! Amazon CloudSearch! Amazon CloudWatch! Amazon Direct Connect! Amazon DynamoDB! Amazon EBS! Amazon EC2! Amazon ElastiCache! Amazon Elastic Transcoder! Amazon EMR! Amazon Glacier! Amazon IAM! Amazon Mechanical Turk! Amazon RDS! Amazon Redshi"! Amazon Route53! Fastest Growing AWS Service Ever! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! Amazon Redshi"! !

Slide 14

Slide 14 text

You can manage AWS services via! the AWS Management Console, but…!

Slide 15

Slide 15 text

AWS services each have an API,! so you can control your resources! through programs and scripts.!

Slide 16

Slide 16 text

So let's provision some servers! from PHP by using the AWS SDK for PHP! to talk to the Amazon EC2 API! Amazon EC2!

Slide 17

Slide 17 text

get('ec2');   $result  =  $ec2-­‐>runInstances(array(      'ImageId'            =>  'ami-­‐af45d59f',      'MinCount'          =>  1,      'MaxCount'          =>  3,      'InstanceType'  =>  'm1.small',   ));     $ids  =  $result-­‐>getPath('Instances/*/InstanceId');   $ec2-­‐>waitUntilInstanceRunning(array(      'InstanceIds'  =>  $ids,   ));   echo  'Provisioned  '  .  count($ids)  .  '  servers.';    

Slide 18

Slide 18 text

AWS SDKs and Tools! PHP • Java • Python • .NET! Ruby • Node.js • iOS • Android! SDKs! AWS CLI • Visual Studio Plugin! Eclipse Plugin • PowerShell Tools! Management Console • iOS App! ! Tools! https://github.com/aws! !

Slide 19

Slide 19 text

AWS SDK for PHP! •  PHP 5.3+, PSR compliant! •  Built on top of Guzzle (guzzlephp.org)! •  Persistent connections, parallel requests! •  Easy pagination, "waiters", other helpers! •  Event hooks, plugins, wire logging!

Slide 20

Slide 20 text

Installing the PHP SDK! •  Composer! •  Phar Download! •  Zip Download! •  PEAR!

Slide 21

Slide 21 text

SDK History! •  Tarzan [2006] ( @skyzyx )! •  CloudFusion [2007] ( @skyzyx )! •  AWS SDK for PHP [2010]! ( @skyzyx & @jeremeamia )! •  AWS SDK for PHP 2 [Late 2012]! ( @mtdowling & @jeremeamia )!

Slide 22

Slide 22 text

require  'vendor/autoload.php';     $s3  =  Aws\S3\S3Client::factory(array(        'key'        =>  'your_aws_access_key_id',      'secret'  =>  'your_aws_secret_key',   ));     $body  =  fopen('/path/to/file',  'r');   $result  =  $s3-­‐>putObject(array(      'Bucket'  =>  'my-­‐cool-­‐photos',      'Key'        =>  'photo.jpg',      'Body'      =>  $body,      'ACL'        =>  'public-­‐read',   ));  

Slide 23

Slide 23 text

Concepts in the SDK! •  Client Factories & Service Builder! •  Commands! •  Modeled Results! •  Iterators! •  Waiters! •  Events & Plugins!

Slide 24

Slide 24 text

use  Aws\Ec2\Ec2Client;     $client  =  Ec2Client::factory(array(        'key'        =>  'your-­‐aws-­‐access-­‐key-­‐id',      'secret'  =>  'your-­‐aws-­‐secret-­‐key',      'region'  =>  'us-­‐west-­‐2',   ));   Client Factory!

Slide 25

Slide 25 text

use  Aws\Common\Aws;     $aws  =  Aws::factory(array(        'key'        =>  'your-­‐aws-­‐access-­‐key-­‐id',      'secret'  =>  'your-­‐aws-­‐secret-­‐key',      'region'  =>  'us-­‐west-­‐2',   ));     $client1  =  $aws-­‐>get('ec2');   $client2  =  $aws-­‐>get('ec2');   var_dump($client1  ===  $client2);   Service Builder!

Slide 26

Slide 26 text

Commands! •  Encapsulates an operation to AWS! •  Contains Request and Response objects! •  Allows you set and get parameters! •  Returns modeled results when executed!

Slide 27

Slide 27 text

Commands - Shorthand! $result  =  $s3-­‐>listObjects(array(      'Bucket'  =>  'my-­‐bucket-­‐name'   ));     echo  $result['Contents'][0]['Key'];  

Slide 28

Slide 28 text

$command  =  $s3-­‐>getCommand('ListObjects');   $command-­‐>set('Bucket',  'my-­‐bucket-­‐name');   $command['Bucket']  =  'my-­‐bucket-­‐name';     $result  =  $command-­‐>getResult();   echo  $result['Contents'][0]['Key'];     $request  =  $command-­‐>getRequest();   $response  =  $command-­‐>getResponse();   echo  $response-­‐>getStatusCode();   echo  $response-­‐>getHeader('Content-­‐Length');     The Command Object!

Slide 29

Slide 29 text

$c1  =  $s3-­‐>getCommand('PutObject',  array(      'Bucket'  =>  'my-­‐bucket-­‐name',      'Key'        =>  'my-­‐first-­‐key',      'Body'      =>  fopen('path/to/file1',  'r')   ));   $c2  =  $s3-­‐>getCommand('PutObject',  array(      'Bucket'  =>  'my-­‐bucket-­‐name',      'Key'        =>  'my-­‐second-­‐key',      'Body'      =>  fopen('path/to/file2',  'r')   ));     $s3-­‐>execute(array($c1,  $c2));   Parallel Commands!

Slide 30

Slide 30 text

Modeled Results! •  Array-like object! •  Follows schema from service description! •  Convenience methods like getPath()   $result  =  $s3-­‐>listBuckets();     $result['Buckets'][0]['Name'];   $result-­‐>get('Buckets');   $result-­‐>getPath('Buckets/0/Name');   print_r($result-­‐>toArray());  

Slide 31

Slide 31 text

Waiters! •  Poll resources until available! •  Handle asynchronous and eventually consistent operations more easily! $s3-­‐>createBucket(array(      'Bucket'  =>  'my-­‐bucket'   ));   $s3-­‐>waitUntilBucketExists(array(      'Bucket'  =>  'my-­‐bucket'   ));  

Slide 32

Slide 32 text

Iterators! •  Iterate through entire result sets! •  No handling of markers or tokens! •  Uses SPL iterators! $list  =  $s3-­‐>getListObjectsIterator([      'Bucket'  =>  'my-­‐bucket'   ]);   foreach  ($list  as  $object)  {      echo  $object['Key']  .  "\n";   }  

Slide 33

Slide 33 text

SDK 1.x – Before Iterators! $dynamo_db  =  new  AmazonDynamoDB();   $start_key  =  null;   $people  =  array();       do  {      $params  =  array(          'TableName'  =>  'people',      );          if  ($start_key)  {        $params['ExclusiveStartKey']  =  array(            'HashKeyElement'  =>  array(                'S'  =>  $start_key            )        );        $start_key  =  null;    }      $response  =  $dynamo_db-­‐>scan($params);    if  ($response-­‐>isOK())  {        foreach   ($response-­‐>body-­‐>Items  as  $item)  {            echo  (string)  $item-­‐>name-­‐>S;        }                  if  ($response-­‐>body-­‐>LastEvaluatedKey)  {            $start_key  =  (string)  $response-­‐>body   -­‐>LastEvaluatedKey-­‐>HashKeyElement-­‐>S;        }      }  else  {                  throw  new  DynamoDB_Exception('…');    } }  while  ($start_key);

Slide 34

Slide 34 text

SDK 1.x – Before Iterators! $dynamo_db  =  new  AmazonDynamoDB();   $start_key  =  null;   $people  =  array();       do  {      $params  =  array(          'TableName'  =>  'people',      );          if  ($start_key)  {        $params['ExclusiveStartKey']  =  array(            'HashKeyElement'  =>  array(                'S'  =>  $start_key            )        );        $start_key  =  null;    }      $response  =  $dynamo_db-­‐>scan($params);    if  ($response-­‐>isOK())  {        foreach   ($response-­‐>body-­‐>Items  as  $item)  {            echo  (string)  $item-­‐>name-­‐>S;        }                  if  ($response-­‐>body-­‐>LastEvaluatedKey)  {            $start_key  =  (string)  $response-­‐>body   -­‐>LastEvaluatedKey-­‐>HashKeyElement-­‐>S;        }      }  else  {                  throw  new  DynamoDB_Exception('…');    } }  while  ($start_key);

Slide 35

Slide 35 text

$db  =  $aws-­‐>get('DynamoDb');     $scan  =  $db-­‐>getScanIterator(array(      'TableName'              =>  'People',      'AttributesToGet'  =>  array('Id',  'Name')   ));     foreach  ($scan  as  $person)  {      echo  $item['Name']['S'];   }     Example: Scan Iterator!

Slide 36

Slide 36 text

Events & Event Listeners! •  Event slots in various parts of SDK! (Clients, Requests, Waiters, Batches, etc.)! •  Inject logic without extending classes! •  Every client has an instance of the Symfony2 EventDispatcher! $s3-­‐>getEventDispatcher()        -­‐>addListener('',  );  

Slide 37

Slide 37 text

Plugins! •  Implemented as event subscribers! •  Request signing implemented this way! •  Many built-in plugins from Guzzle including easy wire logging! use  Guzzle\Plugin\Log\LogPlugin;   $s3-­‐>addSubscriber(          LogPlugin::getDebugPlugin()   );  

Slide 38

Slide 38 text

Simple Funny Face! Sharing App on AWS!

Slide 39

Slide 39 text

Funny Face Sharing App!

Slide 40

Slide 40 text

Funny Face Sharing App!

Slide 41

Slide 41 text

AWS Services for our App! $ $AWS Elastic Beanstalk! $ $Amazon S3! $ $( Simple Storage Service )! $ $Amazon DynamoDB! $ $AWS IAM! $ $( Identity and Access Management )!

Slide 42

Slide 42 text

AWS Elastic Beanstalk! •  Easy to get started! •  PHP 5.3 or PHP 5.4! •  Does load balancing and auto scaling! •  Deploy via Git, upload (console), or S3 (API)! •  Installs Composer dependencies for you! •  Customize via API/console, ebextensions con%g, and custom hook scripts!

Slide 43

Slide 43 text

require  __DIR__  .  '/vendor/autoload.php';     use  Aws\Common\Enum\Region;   use  Aws\Silex\AwsServiceProvider;   use  Silex\Application;     $app  =  new  Application;   $app-­‐>register(new  AwsServiceProvider(),  array(      'aws.config'  =>  array(              'key'        =>  'AKEXAMPLE8FOO29JBAR8Q',              'secret'  =>  'Sf0Example24Foo0J4Bar3XBaz34',            'region'  =>  Region::US_EAST_1,      )   ));   Let's Use Silex, Twig, & AWS!

Slide 44

Slide 44 text

SDK Third-party Integrations! •  Silex service provider! •  Laravel 4 service provider! •  Zend Framework 2 module! •  Gaufrette adapter!

Slide 45

Slide 45 text

require  __DIR__  .  '/vendor/autoload.php';     use  Aws\Common\Enum\Region;   use  Aws\Silex\AwsServiceProvider;   use  Silex\Application;     $app  =  new  Application;   $app-­‐>register(new  AwsServiceProvider(),  array(      'aws.config'  =>  array(              'key'        =>  'AKEXAMPLE8FOO29JBAR8Q',              'secret'  =>  'Sf0Example24Foo0J4Bar3XBaz34',            'region'  =>  Region::US_EAST_1,      )   ));   Credential Problem!

Slide 46

Slide 46 text

IAM Roles & Instance Pro%les! •  An IAM Role lets you give other AWS users and services access to your AWS resources.! •  An IAM Instance Pro%le is an association of an IAM Role to an Amazon EC2 Instance.! •  The AWS SDK for PHP will automatically use Instance Pro%le Credentials if available.! •  You can con%gure your Elastic Beanstalk environment with an Instance Pro%le.!

Slide 47

Slide 47 text

require  __DIR__  .  '/vendor/autoload.php';     use  Aws\Common\Enum\Region;   use  Aws\Silex\AwsServiceProvider;   use  Silex\Application;     $app  =  new  Application;   $app-­‐>register(new  AwsServiceProvider(),  array(      'aws.config'  =>  array(              'region'  =>  Region::US_EAST_1,      )   ));   Instance Pro%le Credentials! Do not provide any credentials, and the SDK will automatically use your Instance Profile Credentials.

Slide 48

Slide 48 text

$app-­‐>get('/photos',  function  ()  use  ($app)  {      $db  =  $app['aws']-­‐>get('dynamodb');      $faces  =  $db-­‐>getScanIterator([              'TableName'  =>  'funny-­‐face'      ]);        return  $app['twig']-­‐>render('index.twig',[              'faces'  =>  $faces      ]);   });   Index Controller!

Slide 49

Slide 49 text

$app-­‐>get('/photos',  function  ()  use  ($app)  {      $db  =  $app['aws']-­‐>get('dynamodb');      $faces  =  $db-­‐>getScanIterator([              'TableName'  =>  'funny-­‐face'      ]);        return  $app['twig']-­‐>render('index.twig',[              'faces'  =>  $faces      ]);   });   Index Controller!

Slide 50

Slide 50 text

The Shape of an Item! {        "src":  {              "S":  "https://funny-­‐face.s3.amazonaws.com/2rlDm.jpg"        },        "caption":  {              "S":  "You  had  one  job!"        }  ,        "size":  {              "N":  "205993423"        }   },  

Slide 51

Slide 51 text

use  Aws\DynamoDb\Iterator\ItemIterator  as  Items;   $app-­‐>get('/photos',  function  ()  use  ($app)  {      $db  =  $app['aws']-­‐>get('dynamodb');      $faces  =  new  Items($db-­‐>getScanIterator([              'TableName'  =>  'funny-­‐face'      ]);        return  $app['twig']-­‐>render('index.twig',[              'faces'  =>  $faces      ]);   });   Index Controller Revisited!

Slide 52

Slide 52 text

$app-­‐>match('/photos/add',  function()  use($app)  {      //  ...  ($file  is  a  Symfony\Component\HttpFoundation\File\UploadedFile)      $s3  =  $app['aws']-­‐>get('s3');      $url  =  $s3-­‐>putObject([              'Bucket'          =>  'funny-­‐face',              'Key'                =>  $file-­‐>getFileName(),              'SourceFile'  =>  $file-­‐>getPathname(),              'ACL'                =>  CannedAcl::PUBLIC_READ,      ])-­‐>get('ObjectURL');      //  ...   });   Add Controller - Upload!

Slide 53

Slide 53 text

$app-­‐>match('/photos/add',  function($request)  use($app)  {      //  ...      $db  =  $app['aws']-­‐>get('dynamodb');      $msg  =  $request-­‐>request-­‐>get('caption',  'None');      $db-­‐>putItem([              'TableName'  =>  'funny-­‐face',              'Item'            =>  [                      'src'          =>  ['S'  =>  $url],                      'caption'  =>  ['S'  =>  $msg]              ],      ]);      //  ...   });   Add Controller - Save!

Slide 54

Slide 54 text

AWS OpsWorks! •  DevOps solution for apps! •  Organized w/ stacks & layers! •  Deploy from a GitHub repo! •  Customize with Chef recipes! •  Nice management console!

Slide 55

Slide 55 text

Special Features! in the AWS SDK for PHP!

Slide 56

Slide 56 text

$s3  =  $aws-­‐>get('S3');   $uploader  =  UploadBuilder::newInstance()      -­‐>setClient($s3)      -­‐>setSource('./videos/video42.mov')      -­‐>setBucket('app-­‐media')      -­‐>setKey('videos/video42.mov')      -­‐>setConcurrency(3)      -­‐>build();   Multipart Uploader!

Slide 57

Slide 57 text

$s3-­‐>upload(      'app-­‐media',                    //  Bucket      'videos/video42.mov',  //  Key      fopen('/tmp/vidz/video42.mov',  'r')   );   Simple Upload! Automatically uses single or multipart upload for you depending on %le size.!

Slide 58

Slide 58 text

$s3-­‐>registerStreamWrapper();     $path  =  's3://jcl-­‐files/logs/04.log';   if  ($file  =  fopen($path,  'r'))  {      while  (!feof($file))  {          echo  fgets($file);      }      fclose($file)   }   Amazon S3 Stream Wrapper!

Slide 59

Slide 59 text

$s3-­‐>registerStreamWrapper();     $finder  =  new  Finder();   $finder-­‐>files()      -­‐>in('s3://jcl-­‐files/family-­‐videos')      -­‐>size('<  50M')      -­‐>date('since  1  year  ago');     foreach  ($finder  as  $file)  {      echo  $file-­‐>getFilename()  .  "\n";   }   Stream Wrapper + Symfony Finder!

Slide 60

Slide 60 text

Need Help with the SDK?! •  Homepage http://aws.amazon.com/sdkforphp/! •  Github https://github.com/aws/aws-sdk-php! •  User Guide http://docs.aws.amazon.com/aws-sdk-php-2/guide/latest/! •  API Docs http://docs.aws.amazon.com/aws-sdk-php-2/latest/! •  Blog http://blogs.aws.amazon.com/php! •  Forum https://forums.aws.amazon.com/forum.jspa?forumID=80!