In real-world applications, sometimes you need to interact or communicate with external web services. For this process, you have to send HTTP requests to web services and receive the response. When it comes to PHP, you can deal with web services either using cURL or Guzzle HTTP Client.
The cURL is a little bit difficult for beginners. Another drawback with cURL is your server should have installed the cURL extension or else it won’t work.
On another hand, A Guzzle HTTP Client is a better 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 separate extension on your server. The structure of code written in Guzzle is much cleaner than in 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 HTTP Requests.
- GET
- POST
- PUT
- PATCH
- DELETE
- File Upload or multipart
- Copy the file from the remote URL to a local directory
To learn Guzzle practically, I’ll use the following 2 services. These are the web services with whom we’ll deal programmatically.
- REQ|RES: This service provides fake REST APIs 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 of Guzzle Library
First, we start with the installation of the Guzzle package. The recommended way to install it using the Composer. Open the terminal in your project root directory and run the command.
composer require guzzlehttp/guzzle
Upon installing the library, you are ready to send HTTP requests. We will cover all major HTTP requests usually required for the application. Once you are familiar with it, you can explore other request options on your own.
How to Send HTTP Requests 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;
GET Request using Guzzle
If you look at the REQ|RES website, 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, you should send a GET request to this endpoint https://reqres.in/api/users?page=2
.
In Guzzle, we’ll integrate this 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_URL which is https://reqres.in
. The actual endpoint is /api/users
and it requires a GET parameter as page=2
. In Guzzle, you send GET parameters using the query
as shown in the above code. To the query
array, you can pass as many parameters.
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.
The status codes help to figure out whether a request is successfully executed or not. Using Guzzle, you can get the status code from the HTTP response as shown below.
echo $response->getStatusCode(); //output is 200 for above GET request
Following this practice, you may write the above code as follows.
if (200 == $response->getStatusCode()) {
$body = $response->getBody();
$arr_body = json_decode($body);
print_r($arr_body);
}
POST Request using Guzzle
There are 2 types of POST requests. You may post parameters as application/x-www-form-urlencoded
request or upload JSON-encoded data as a body of the request. Let’s see both options one by one.
The user can post JSON-encoded data using Guzzle as shown below. Notice the word json 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
request, you will 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',
]);
$client->request('POST', '/endpoint_here', [
'form_params' => [
'foo' => 'bar',
'baz' => ['hi', 'there!']
]
]);
Set Authorization Header in Guzzle
It may be possible REST API service asks you to send the Authorization header in each HTTP request. The user can set this header in the Guzzle as shown below.
<?php
$client->request('POST', '/endpoint_here', [
"headers" => [
"Authorization" => "Bearer TOKEN_VALUE"
],
'form_params' => [
'foo' => 'bar',
'baz' => ['hi', 'there!']
]
]);
PUT, PATCH, DELETE Request using Guzzle
So far you should have acquainted with the Guzzle library. Going ahead, let’s take a look at the next HTTP requests.
The PUT and PATCH requests are used to update the resources. However, these 2 requests differ from each other.
PUT request overwrites the entire entity if it already exists, and creates a new resource if it doesn’t exist. For instance, 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' => 'John',
'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 required to send only specific data that need to be updated. It won’t affect or change other information. So if you want to update the name of a person, you will send only that value.
<?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' => 'John',
]
]);
//get status code using $response->getStatusCode();
$body = $response->getBody();
$arr_body = json_decode($body);
print_r($arr_body);
A DELETE request is straightforward. Just 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
Using Guzzle, you can copy a file from a remote server to your local directory. Let’s say you want to copy this image 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(To External Service)
For uploading files, you need to set the body of the request as multipart/form-data
in Guzzle(by passing multipart
array). The below code can be used for uploading a file to an external service.
<?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 optimizes the images. For this, you need to POST your image to their endpoint. In response, you will get an optimized version of your images.
<?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();
}
Conclusion
In this tutorial, we have covered major HTTP Requests that are integrated into the web application. I hope you understand how to use Guzzle HTTP Client and can easily use it on your website. I would like to hear 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.