├── .gitignore ├── README.md ├── composer.json ├── sample ├── guzzle-1a.php ├── guzzle-1b.php ├── guzzle-1c.php ├── guzzle-2.php ├── guzzle-3.php ├── guzzle-4.php ├── guzzle-5.php ├── guzzle-6.php └── twilio-1.php └── src ├── Client.php └── twilio-api.php /.gitignore: -------------------------------------------------------------------------------- 1 | composer.lock 2 | /vendor -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Sunshine PHP Guzzle Tutorial 2 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jeremeamia/twilio-guzzle", 3 | "require": { 4 | "guzzlehttp/guzzle": "~5.0", 5 | "guzzlehttp/guzzle-services": "*", 6 | "guzzlehttp/retry-subscriber": "*", 7 | "guzzlehttp/log-subscriber": "*" 8 | }, 9 | "authors": [ 10 | { 11 | "name": "Jeremy Lindblom", 12 | "email": "jeremeamia@gmail.com" 13 | } 14 | ], 15 | "autoload": { 16 | "psr-4": { 17 | "Twilio\\": "src/" 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /sample/guzzle-1a.php: -------------------------------------------------------------------------------- 1 | createRequest('GET', 'http://httpbin.org/get'); 8 | $response = $httpClient->send($request); 9 | 10 | echo "REQUEST:\n\n{$request}\n"; 11 | echo "RESPONSE:\n\n{$response}\n"; 12 | -------------------------------------------------------------------------------- /sample/guzzle-1b.php: -------------------------------------------------------------------------------- 1 | get('http://httpbin.org/get'); 8 | 9 | -------------------------------------------------------------------------------- /sample/guzzle-1c.php: -------------------------------------------------------------------------------- 1 | get('http://httpbin.org/get'); 8 | 9 | echo 'Status Code: ' . $response->getStatusCode() . "\n"; 10 | echo 'Content-Type: ' . $response->getHeader('content-type') . "\n"; 11 | echo 'Body: ' . $response->getBody() . "\n"; 12 | print_r($response->json()); 13 | -------------------------------------------------------------------------------- /sample/guzzle-2.php: -------------------------------------------------------------------------------- 1 | getEmitter()->attach($logger); 14 | 15 | // Send a post request with "form data" in the body. 16 | $httpClient->post('https://httpbin.org/post', [ 17 | 'body' => [ 18 | 'first_name' => 'Jeremy', 19 | 'last_name' => 'Lindblom', 20 | 'age' => 30, 21 | ] 22 | ]); 23 | -------------------------------------------------------------------------------- /sample/guzzle-3.php: -------------------------------------------------------------------------------- 1 | 'https://httpbin.org', 12 | 'defaults' => [ 13 | 'auth' => ['user', 'pass'], 14 | 'headers' => [ 15 | 'X-Requested-With' => 'Guzzle' 16 | ] 17 | ] 18 | ]); 19 | 20 | // Attach a subscriber for logging the request and response. 21 | $logger = new LogSubscriber(STDOUT, new Formatter(Formatter::DEBUG)); 22 | $httpClient->getEmitter()->attach($logger); 23 | 24 | // Send a get request to and endpoint requiring basic auth. 25 | $httpClient->get('basic-auth/user/pass'); 26 | -------------------------------------------------------------------------------- /sample/guzzle-4.php: -------------------------------------------------------------------------------- 1 | 'https://httpbin.org', 11 | ]); 12 | 13 | // Attach a subscriber for logging the request and response. 14 | $logger = new LogSubscriber(STDOUT, new Formatter(Formatter::DEBUG)); 15 | $httpClient->getEmitter()->attach($logger); 16 | 17 | // Create a generator that emits PUT requests. 18 | $createPutRequests = function ($limit, $start = 1) use ($httpClient) { 19 | for ($i = $start; $i <= $limit; $i++) { 20 | yield $httpClient->createRequest('PUT', 'put', [ 21 | 'json' => [ 22 | 'first_name' => 'John' . str_pad($i, 4, '0', STR_PAD_LEFT), 23 | 'last_name' => 'Doe', 24 | 'age' => rand(18, 60), 25 | ] 26 | ]); 27 | } 28 | }; 29 | 30 | // Execute a batch of requests. 31 | $httpClient->sendAll($createPutRequests(5)); 32 | -------------------------------------------------------------------------------- /sample/guzzle-5.php: -------------------------------------------------------------------------------- 1 | 'https://httpbin.org', 12 | ]); 13 | 14 | // Attach a subscriber for logging the request and response. 15 | $logger = new LogSubscriber(STDOUT, new Formatter(Formatter::DEBUG)); 16 | $httpClient->getEmitter()->attach($logger); 17 | 18 | // Attach an event listener that adds an additional header. 19 | $httpClient->getEmitter()->on('before', function (BeforeEvent $event) { 20 | $event->getRequest()->addHeader('X-Requested-With', 'Guzzle'); 21 | }); 22 | 23 | $httpClient->get('get'); 24 | -------------------------------------------------------------------------------- /sample/guzzle-6.php: -------------------------------------------------------------------------------- 1 | 'https://httpbin.org', 11 | ]); 12 | 13 | // Attach a subscriber for logging the request and response. 14 | $httpClient->getEmitter()->on('before', function (BeforeEvent $event) { 15 | echo 'Request: ' . $event->getRequest()->getUrl() . "\n"; 16 | }); 17 | $httpClient->getEmitter()->on('end', function (EndEvent $event) { 18 | echo 'Response: ' . $event->getResponse()->json()['url'] . "\n"; 19 | }); 20 | 21 | // Execute two requests asyncronously. 22 | $httpClient->get('delay/4', ['future' => true]); 23 | $httpClient->get('delay/2', ['future' => true]); 24 | -------------------------------------------------------------------------------- /sample/twilio-1.php: -------------------------------------------------------------------------------- 1 | getenv('TWILIO_ACCOUNT_SID'), 7 | 'auth_token' => getenv('TWILIO_AUTH_TOKEN'), 8 | ]); 9 | 10 | $result = $twilioClient->getAccount(); 11 | echo "Account Friendly Name: {$result['friendly_name']}\n"; 12 | 13 | $result = $twilioClient->sendMessage([ 14 | 'From' => '+12067017747', 15 | 'To' => '+14802055465', 16 | 'Body' => 'Hello, Jeremy!', 17 | ]); 18 | echo "Message SID: {$result['sid']}\n"; 19 | -------------------------------------------------------------------------------- /src/Client.php: -------------------------------------------------------------------------------- 1 | 3, 25 | 'description_path' => __DIR__ . '/twilio-api.php', 26 | ]; 27 | 28 | // Create the Twilio client. 29 | parent::__construct( 30 | $this->getHttpClientFromConfig($config), 31 | $this->getDescriptionFromConfig($config), 32 | $config 33 | ); 34 | 35 | // Ensure that the credentials are set. 36 | $this->applyCredentials($config); 37 | 38 | // Ensure that ApiVersion is set. 39 | $this->setConfig( 40 | 'defaults/ApiVersion', 41 | $this->getDescription()->getApiVersion() 42 | ); 43 | } 44 | 45 | private function getHttpClientFromConfig(array $config) 46 | { 47 | // If a client was provided, return it. 48 | if (isset($config['http_client'])) { 49 | return $config['http_client']; 50 | } 51 | 52 | // Create a Guzzle HttpClient. 53 | $clientOptions = isset($config['http_client_options']) 54 | ? $config['http_client_options'] 55 | : []; 56 | $client = new HttpClient($clientOptions); 57 | 58 | // Attach request retry logic. 59 | $client->getEmitter()->attach(new RetrySubscriber([ 60 | 'max' => $config['max_retries'], 61 | 'filter' => RetrySubscriber::createChainFilter([ 62 | RetrySubscriber::createStatusFilter(), 63 | RetrySubscriber::createCurlFilter(), 64 | ]), 65 | ])); 66 | 67 | return $client; 68 | } 69 | 70 | private function getDescriptionFromConfig(array $config) 71 | { 72 | // If a description was provided, return it. 73 | if (isset($config['description'])) { 74 | return $config['description']; 75 | } 76 | 77 | // Load service description data. 78 | $data = is_readable($config['description_path']) 79 | ? include $config['description_path'] 80 | : null; 81 | 82 | return new Description($data); 83 | } 84 | 85 | private function applyCredentials(array $config) 86 | { 87 | // Ensure that the credentials have been provided. 88 | if (!isset($config['account_sid'])) { 89 | throw new \InvalidArgumentException( 90 | 'You must provide a Twilio account SID.' 91 | ); 92 | } 93 | if (!isset($config['auth_token'])) { 94 | throw new \InvalidArgumentException( 95 | 'You must provide a Twilio auth token.' 96 | ); 97 | } 98 | 99 | // Set credentials for authentication based on Twilio's requirements. 100 | $this->getHttpClient()->setDefaultOption('auth', [ 101 | $config['account_sid'], 102 | $config['auth_token'], 103 | ]); 104 | 105 | // Include the account SID in every request. 106 | $this->setConfig('defaults/AccountSid', $config['account_sid']); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/twilio-api.php: -------------------------------------------------------------------------------- 1 | 'https://api.twilio.com', 3 | 'apiVersion' => '2010-04-01', 4 | 'operations' => [ 5 | 'GetAccount' => [ 6 | 'httpMethod' => 'GET', 7 | 'uri' => '/{ApiVersion}/Accounts/{AccountSid}.json', 8 | 'responseModel' => 'Resource', 9 | 'parameters' => [ 10 | 'AccountSid' => [ 11 | 'required' => true, 12 | 'type' => 'string', 13 | 'location' => 'uri', 14 | ], 15 | 'ApiVersion' => [ 16 | 'required' => true, 17 | 'type' => 'string', 18 | 'location' => 'uri', 19 | ], 20 | ] 21 | ], 22 | 'SendMessage' => [ 23 | 'httpMethod' => 'POST', 24 | 'uri' => '/{ApiVersion}/Accounts/{AccountSid}/Messages.json', 25 | 'responseModel' => 'Resource', 26 | 'parameters' => [ 27 | 'AccountSid' => [ 28 | 'required' => true, 29 | 'type' => 'string', 30 | 'location' => 'uri', 31 | ], 32 | 'ApiVersion' => [ 33 | 'required' => true, 34 | 'type' => 'string', 35 | 'location' => 'uri', 36 | ], 37 | 'From' => [ 38 | 'required' => true, 39 | 'type' => 'string', 40 | 'location' => 'postField', 41 | ], 42 | 'To' => [ 43 | 'required' => true, 44 | 'type' => 'string', 45 | 'location' => 'postField', 46 | ], 47 | 'Body' => [ 48 | 'type' => 'string', 49 | 'location' => 'postField', 50 | ], 51 | 'MediaUrl' => [ 52 | 'type' => 'string', 53 | 'location' => 'postField', 54 | ], 55 | 'StatusCallback' => [ 56 | 'type' => 'string', 57 | 'location' => 'postField', 58 | ], 59 | 'ApplicationSid' => [ 60 | 'type' => 'string', 61 | 'location' => 'postField', 62 | ], 63 | ], 64 | ], 65 | ], 66 | 'models' => [ 67 | 'Resource' => [ 68 | 'type' => 'object', 69 | 'additionalProperties' => [ 70 | 'location' => 'json', 71 | ] 72 | ], 73 | ] 74 | ]; 75 | --------------------------------------------------------------------------------