Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 54

Sending HTTP Requests with Guzzle

Recommended resources

Hello! Welcome to the tenth module of our PHP Mastery course.

In the previous module, you did an excellent job of building your own RESTful API and, crucially, securing it with an API key authentication system. You've experienced what it's like to be an API provider.

In this lesson, we're going to flip the script and become an API consumer. Your applications will often need to communicate with external services—to fetch data, send notifications, or process payments. Today, we'll learn how to do just that. Our goal is to make HTTP requests to external APIs using a client like Guzzle.

1. Why Use an HTTP Client?

You can make HTTP requests in PHP using built-in functions like file_get_contents() or the cURL extension. However, these tools can be cumbersome for complex tasks. For example, building a POST request with a JSON body and custom headers using cURL requires setting many options and can be hard to read.

This is where HTTP client libraries come in. They provide a clean, object-oriented abstraction layer over the low-level details of HTTP. The most popular and de facto standard HTTP client in the PHP ecosystem is Guzzle.

Guzzle PHP HTTP Client Documentation Screenshot
Guzzle provides a simple and powerful interface for making HTTP requests, handling everything from authentication and query parameters to redirects and cookies.

Using a client like Guzzle makes your code more readable, maintainable, and easier to test. It simplifies sending data, managing headers, and handling responses.


2. Setting Up Your Project with Guzzle

Let's start by setting up a new project to practice consuming an API. We'll use the JSON Placeholder API, a free online REST API for testing and prototyping.

First, create a new project directory and navigate into it. Since Guzzle is a package, we'll use Composer to install it, just as you did in Module 4.

  1. Initialize Composer (if needed) and install Guzzle:

    composer require guzzlehttp/guzzle:^7.0
    
  2. Create an index.php file. This will be our workspace. At the top of the file, make sure to include Composer's autoloader, which will handle loading the Guzzle classes for us.

    <?php
    
    require 'vendor/autoload.php';
    
    // Our code will go here
    

That's it! Guzzle is now installed and ready to use in your project.


3. Making Your First GET Request

The core of Guzzle is the Client class. You create a client instance and then use it to send requests. Let's make a simple GET request to fetch a single post from the JSON Placeholder API.

The following video provides an excellent walkthrough of installing Guzzle and making a basic request. It refactors a cURL implementation to use Guzzle, clearly showing the benefits.

Refactor cURL to Guzzle With Retry Logic - Multiple API Integrations - Full PHP 8 Tutorial

Watch this clip from the 'Program With Gio' channel. It demonstrates how to install Guzzle, create a client with a base URI and timeout, and make a simple GET request.

Watch from 04:33 to 06:51. Pay close attention to how the Client is instantiated with options and how the get() method is called with a relative URL.

Let's put that into practice in our index.php file.

Step 1: Create a Guzzle Client

It's a best practice to configure the client with a base_uri. This allows you to make requests using relative URLs, keeping your code clean.

<?php

require 'vendor/autoload.php';

use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;

// 1. Create a Guzzle client with a base URI and a timeout
$client = new Client([
    'base_uri' => 'https://jsonplaceholder.typicode.com',
    'timeout'  => 2.0, // Timeout after 2 seconds
]);

echo "Client created.\n";

Step 2: Send the Request

Now, use the client to send a GET request. Guzzle provides convenient "magic" methods for each HTTP verb, like get(), post(), put(), etc. These methods return a Response object.

Because network requests can fail for many reasons (e.g., DNS issues, timeouts, server errors), it's crucial to wrap your request code in a try...catch block to handle potential exceptions.

// In index.php, after creating the client

try {
    // 2. Send a GET request to the '/posts/1' endpoint
    $response = $client->get('/posts/1');
    echo "Request sent successfully.\n";

} catch (RequestException $e) {
    // Handle request exceptions (e.g., connection errors, timeouts)
    echo "Error: " . $e->getMessage();
    exit;
}

Step 3: Handle the Response

If the request is successful, you'll get a response object that complies with the PSR-7 ResponseInterface. This object contains everything you need: the status code, headers, and the body of the response.

The response body is returned as a stream. This is an efficient way to handle potentially large responses, as it doesn't require loading the entire body into memory at once. To get the full content of the body as a string, you need to call the getContents() method on the stream.

This next short video clip shows exactly how to get the body from the response and decode it.

Refactor cURL to Guzzle With Retry Logic - Multiple API Integrations - Full PHP 8 Tutorial

This clip continues from where the last one left off, showing how to access the response body.

Watch from 07:01 to 07:43. Focus on the chain $response->getBody()->getContents() to retrieve the body as a string.

Let's add this to our code to complete the script.

// In index.php, inside the try block after the request

// 3. Get the response details
$statusCode = $response->getStatusCode();
$body = $response->getBody()->getContents();

// 4. Display the results
echo "Status Code: " . $statusCode . "\n\n";
echo "Response Body:\n";
echo $body;

Now, run your script from the terminal: php index.php. You should see a 200 status code and a JSON object representing the fetched post.


4. Sending Request Options

Most API calls aren't as simple as fetching a single, static resource. You'll often need to send additional data, like query parameters to filter results. Guzzle makes this easy by accepting an array of options as the second argument to its request methods.

For a deeper dive into Guzzle's capabilities, its official documentation is the best resource.

Quickstart

The Guzzle 'Quickstart' documentation is the definitive guide. We'll look at the sections for creating a client and specifying query string parameters.

First, review the 'Creating a Client' section to reinforce what we just did. Then, read the short section titled 'Query String Parameters'. It shows the different ways to add parameters to your request.

Let's modify our code to fetch all posts belonging to userId 1. We can do this by sending a GET request to /posts and using the query option.

<?php

require 'vendor/autoload.php';

use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;

$client = new Client([
    'base_uri' => 'https://jsonplaceholder.typicode.com',
    'timeout'  => 2.0,
]);

try {
    // Send a GET request to '/posts' with a query parameter
    $response = $client->get('/posts', [
        'query' => ['userId' => 1]
    ]);

    $statusCode = $response->getStatusCode();
    $body = $response->getBody()->getContents();

    echo "Status Code: " . $statusCode . "\n\n";
    // The body will be a JSON array of posts.
    // We can use print_r on the decoded version to see it clearly.
    print_r(json_decode($body, true));

} catch (RequestException $e) {
    echo "Error: " . $e->getMessage();
}

When you run this updated script, Guzzle automatically builds the correct URL (https://jsonplaceholder.typicode.com/posts?userId=1) and you'll receive a JSON array of all posts by that user.


Conclusion

Congratulations! You've successfully used a modern HTTP client to consume an external API. This is a fundamental skill for building applications that integrate with the vast ecosystem of web services.

Key Takeaways:

  • Guzzle is the standard PHP library for making HTTP requests, providing a clean, object-oriented API.
  • You install Guzzle using Composer.
  • The main workflow is to create a Client object, call a request method (e.g., $client->get()), and process the resulting Response object.
  • Best practices include setting a base_uri on the client and wrapping requests in try...catch blocks.
  • The response body is a stream, which you can read into a string using $response->getBody()->getContents().
  • You can pass options like query parameters as an array to customize your requests.

Preview of the Next Lesson:

In our examples, we received a raw JSON string from the API. While we used json_decode() to quickly inspect it, the next lesson will focus entirely on parsing JSON responses and extracting relevant data. You'll learn how to handle different JSON structures and turn that raw data into usable PHP objects and arrays for your application's logic.