In real-world applications, you may need to interact or communicate with external web applications. It requires you to send HTTP requests to another application and receive the response.
In a PHP-based application, you can do it using either cURL or Guzzle HTTP Client.
The cURL option is not relatively easy for a beginner. Also to use the cURL, your server requires a cURL extension.
A Guzzle HTTP Client is an alternative to cURL. It’s a PHP HTTP client that makes it easy to send HTTP requests and trivial to integrate with web services. From my experience, I can say Guzzle is better than cURL. It is simple and easy to use. For Guzzle, you don’t need to have a cURL extension on your server. The structure of code written in Guzzle is much better than cURL.
In this article, I will take a few HTTP requests and show you how to execute them using Guzzle HTTP Client. We are going to cover the following request options.
- GET
- POST
- PUT
- PATCH
- DELETE
- File Upload or multipart
- Copy File from remote URL to a local directory
To learn how to use the above requests with Guzzle, I’ll use the following 2 services. It helps you to understand Guzzle better.
- REQ|RES: This service provides a fake real API for testing HTTP requests.
- reSmush.it API: You send an image to this service and in return receive an optimized version of the image.
Installation
First, we start with the Guzzle installation. The recommended way to install the Guzzle library is through the Composer. Open the terminal in your project root directory and run the command.
composer require guzzlehttp/guzzle
Upon installing the library, we are ready to send HTTP requests. As mentioned, we will cover a major HTTP Request normally required for any application. Once you are familiar with it, you can explore other request options of your own provided by Guzzle.
How to Send HTTP Request using Guzzle
To get started, you need to include a Guzzle environment in your application as follows.
<?php
require_once "vendor/autoload.php";
use GuzzleHttp\Client;
Now let’s write a code for our request options one by one.
GET Request using Guzzle
If you look at the REQ|RES service, they provided different endpoints for each HTTP request.
For the GET request, I will take an example of the ‘LIST USERS’ endpoint. To get the fake users list, it needs to send a GET request to this endpoint https://reqres.in/api/users?page=2
.
In Guzzle, we send the above GET HTTP request as follows.
<?php
require_once "vendor/autoload.php";
use GuzzleHttp\Client;
$client = new Client([
// Base URI is used with relative requests
'base_uri' => 'https://reqres.in',
]);
$response = $client->request('GET', '/api/users', [
'query' => [
'page' => '2',
]
]);
$body = $response->getBody();
$arr_body = json_decode($body);
print_r($arr_body);
Here, I first extracted a ‘base_uri'(common URL) as https://reqres.in
. Then the endpoint is ‘/api/users’ and it requires a GET parameter as ‘page’. In Guzzle, you can send GET parameters to the endpoint using the ‘query’ array as shown in the above code.
Usually, each HTTP response comes with a specific status code. There are several status codes and some of them are as follows.
- 200: Request succeeded.
- 201: The request succeeded and a new resource was created.
- 400: Bad request. It means the server could not understand the request.
Using Guzzle, you can get the HTTP response status code as shown below. It helps to figure out whether a request is successfully executed or not.
echo $response->getStatusCode(); //output is 200 for above GET request
Following this practice, the response in the above code will be written as follows.
if (200 == $response->getStatusCode()) {
$body = $response->getBody();
$arr_body = json_decode($body);
print_r($arr_body);
}
POST Request using Guzzle
Normally, there are 2 types of POST requests. You may send parameters as ‘application/x-www-form-urlencoded’ POST request or upload JSON encoded data as a body of the request. Let’s see both options one by one.
One can POST JSON encoded data using Guzzle as shown below. All you need to do is use a ‘json’ string in an array.
<?php
require_once "vendor/autoload.php";
use GuzzleHttp\Client;
$client = new Client([
// Base URI is used with relative requests
'base_uri' => 'https://reqres.in',
]);
$response = $client->request('POST', '/api/users', [
'json' => [
'name' => 'Sam',
'job' => 'Developer'
]
]);
//get status code using $response->getStatusCode();
$body = $response->getBody();
$arr_body = json_decode($body);
print_r($arr_body);
In the case of ‘application/x-www-form-urlencoded’ POST request, you can POST parameters as follows. Here, instead of ‘json’ you should use ‘form_params’.
<?php
require_once "vendor/autoload.php";
use GuzzleHttp\Client;
$client = new Client([
// Base URI is used with relative requests
'base_uri' => 'BASE_URL_ENDPOINT',
]);
$client->request('POST', '/endpoint_here', [
'form_params' => [
'foo' => 'bar',
'baz' => ['hi', 'there!']
]
]);
It may be possible your API endpoints ask you to send the Authorization token in each HTTP request. The user can send this token as ‘headers’ in your Guzzle request.
<?php
$client->request('POST', '/endpoint_here', [
"headers" => [
"Authorization" => "Bearer TOKEN_VALUE"
],
'form_params' => [
'foo' => 'bar',
'baz' => ['hi', 'there!']
]
]);
PUT, PATCH and DELETE Request using Guzzle
At this point, you may be acquainted with the Guzzle library. Going ahead, let’s have a look at the next HTTP requests.
The PUT and PATCH requests are used to update the resources. However, these 2 requests perform it differently.
PUT overwrites the entire entity if it already exists, and creates a new resource if it doesn’t exist. If you want to update the name of a person, you need to send the entire resource when making a PUT request.
<?php
require_once "vendor/autoload.php";
use GuzzleHttp\Client;
$client = new Client([
// Base URI is used with relative requests
'base_uri' => 'https://reqres.in',
]);
$response = $client->request('PUT', '/api/users/2', [
'json' => [
'name' => 'Sam',
'job' => 'Developer'
]
]);
//get status code using $response->getStatusCode();
$body = $response->getBody();
$arr_body = json_decode($body);
print_r($arr_body);
The PATCH request applies a partial update to the resource. It means you are only required to send the data that you want to update, and it won’t affect or change anything else. So if you want to update the name of a person, you will only be required to send the name parameter.
<?php
require_once "vendor/autoload.php";
use GuzzleHttp\Client;
$client = new Client([
// Base URI is used with relative requests
'base_uri' => 'https://reqres.in',
]);
$response = $client->request('PATCH', '/api/users/2', [
'json' => [
'name' => 'Sam',
]
]);
//get status code using $response->getStatusCode();
$body = $response->getBody();
$arr_body = json_decode($body);
print_r($arr_body);
A DELETE request is straightforward. You just need to hit the given endpoint as follows.
<?php
require_once "vendor/autoload.php";
use GuzzleHttp\Client;
$client = new Client([
// Base URI is used with relative requests
'base_uri' => 'https://reqres.in',
]);
$response = $client->request('DELETE', '/api/users/2');
echo $response->getStatusCode(); //should gives 204
Copy File from Remote Server using Guzzle
If you are looking to copy a file from a remote server to your local directory then Guzzle will be a better option. Let’s say you want to copy this image at https://artisansweb.net/wp-content/uploads/2020/03/blog.jpg
as ‘blog.jpg’ to your local directory. The below code would do the trick.
<?php
require_once "vendor/autoload.php";
use GuzzleHttp\Client;
$fp = fopen('blog.jpg', 'wb');
$client = new \GuzzleHttp\Client();
$request = $client->get('https://artisansweb.net/wp-content/uploads/2020/03/blog.jpg', ['sink' => $fp]);
fclose($fp);
File upload using Guzzle
For uploading files, we need to set the body of the request to a ‘multipart/form-data’ form. The basic code in Guzzle for uploading a file is as below.
<?php
require_once "vendor/autoload.php";
use GuzzleHttp\Client;
$client = new Client([
// Base URI is used with relative requests
'base_uri' => 'BASE_URL_HERE',
]);
$client->request('POST', '/endpoint_here', [
'multipart' => [
[
'name' => 'files', // name value requires by endpoint
'contents' => fopen('/path/to/file', 'r'),
'filename' => 'custom_image.jpg'
],
]
]);
To demonstrate it practically, I will take a live example of reSmush.it API which sends an optimized version of the image in response. For this, you need to POST your image to their endpoint. The code for it using Guzzle is as follows.
<?php
require_once "vendor/autoload.php";
use GuzzleHttp\Client;
try {
$client = new Client([
// Base URI is used with relative requests
'base_uri' => 'http://api.resmush.it',
]);
$response = $client->request('POST', "?qlty=92", [
'multipart' => [
[
'name' => 'files', // name value requires by endpoint
'contents' => fopen(getcwd().'/blog.jpg', 'r'),
'filename' => 'blog.jpg',
'headers' => array('Content-Type' => mime_content_type(getcwd().'/blog.jpg'))
]
]
]);
if (200 == $response->getStatusCode()) {
$response = $response->getBody();
$arr_result = json_decode($response);
print_r($arr_result);
}
} catch (\Exception $e) {
echo $e->getMessage();
}
I hope you understand how to use Guzzle HTTP Client in your PHP applications. Please share your thoughts and suggestions in the comment section below.
Related Articles
- YouTube API – How to Get List of YouTube Videos of Your Channel
- TinyPNG Compress Images Using PHP
- How to Send Email using Gmail API with PHPMailer
If you liked this article, then please subscribe to our YouTube Channel for video tutorials.
How to forward $_FILES data to the API Endpoint using Guzzle
We explained this stuff in this article. See the code written for reSmush.it API.
Thanks. POST with body and Authorization?.
I get an http error 401.
Please:
$client = new GuzzleHttp\Client();
$bodyReturn = $client->request(‘POST’, $urlbase.$url_card, [
‘headers’ => [
‘Authorization’ => ‘Bearer ‘. $pub_key
],
‘json’ => [
‘number’=> ‘4242424242424242’,
‘cvc’=> ‘789’,
‘exp_month’ => ’12’,
‘exp_year’=> ’29’,
‘card_holder’ => ‘Pedro Pérez’
]
])->getBody()->getContents();
I get an http error 405. Thank you.
Short and clear, thanks for sharing.