Get support for mnapoli/bof

If you're new to LTH, please see our FAQ for more information on what it is we do.

Support Options

Unfortunately, there are currently no active helpers for this repository on the platform. Until they become available, we reccomend the following actions:

View Open Issues

Take a look to see if anyone else has experienced the same issue as you and if they managed to solve it.

Open an Issue

Make sure to read any relevant guidelines for opening issues on this repo before posting a new issue.

Sponsor directly

Check out the page and see if there are any options to sponsor this project or it's developers directly.

mnapoli/bof

The HTTP client for humans.

Build Status Latest Version

Why?

Bof is a HTTP client meant to be as user friendly as possible.

It makes the most classic use cases, such as downloading a file, interacting with a JSON API or submitting a form, as simple as possible.

Since Bof is based on Guzzle, more advanced use cases can be addressed by using Guzzle's methods directly.

To sum up, Bof:

  • is user friendly
  • avoids magic strings and arrays for configuration: instead it provides explicit, typed and documented methods that can be autocompleted by IDEs
  • comes with sane defaults: JSON is supported natively, 4xx and 5xx responses throw exceptions, timeouts are short by default
  • is PSR-7 compliant

Future plans:

  • PSR-18 compliance (the HTTP client standard)
  • resiliency mechanisms such as retry, backoff, etc.

Want a short illustration? Here is Bof compared to Guzzle:

// Bof
$http = new Bof\Http;
$createdProduct = $http
    ->withHeader('Authorization', 'Token abcd')
    ->postJson('https://example.com/api/products', [
        'Hello' => 'world',
    ])
    ->getData();

// Guzzle
$client = new GuzzleHttp\Client([
    'headers' => [
        'Authorization' => 'Token abcd',
    ],
]);
$response = $client->request('POST', 'https://example.com/api/products', [
   'json' => [
        'Hello' => 'world',
   ]
]);
$createdProduct = json_decode($response->getBody()->__toString(), true);
if (json_last_error() !== JSON_ERROR_NONE) {
    throw new Exception('There was an error while decoding the JSON response');
}

Do we need a new HTTP client?

Probably not. If this client attracts interest, that may mean that our already popular HTTP clients could use a simpler API targeting the simple use cases. If you maintain a HTTP client and are interested, I would love to merge Bof into existing libraries. Open an issue!

Installation

composer require mnapoli/bof

Usage

$http = new Bof\Http;

$response = $http->get('https://example.com/api/products');

Configuration

The Bof\Http class is immutable.

Configuration is applied by calling withXxx() methods which create a new object every time:

$http = new Bof\Http;

// The header will apply to all subsequent requests
$http = $http->withHeader('Authorization', "Bearer $token");

Remember that withXxx() methods return a copy of the original client:

$http1 = new Bof\Http;

$http2 = $http1->withHeader('Authorization', "Bearer $token");

// $http1 does not have the header applied
// $http2 has the header

Thanks to that pattern, the same methods can be used to apply configuration only for a specific request:

$products = $http->withHeader('Authorization', "Bearer $token")
    ->get('https://example.com/api/products')
    ->getData();

// The next requests will *not* have the `Authorization` header

Responses

Responses are PSR-7 compliant. They also provide methods to facilitate working with JSON responses:

$http = new Bof\Http;

$products = $http->get('https://example.com/api/products')
    ->getData();

The getData() method will decode the JSON response.

All PSR-7 methods are also available:

$response = $http->get('https://example.com/api/products');
echo $response->getStatusCode();
echo $response->getHeader('Content-Length')[0];
echo $response->getBody()->getContents();

Learn more.

Sending JSON data

Using the JSON methods, the data will automatically encoded to JSON. A Content-Type header of application/json will be added.

$http->postJson('https://example.com/api/products', [
    'foo' => 'bar',
]);
// putJson() or patchJson() works as well

Sending form data

Data can also be sent as a application/x-www-form-urlencoded POST request:

$http->postForm('https://example.com/api/products', [
    'foo' => 'bar',
    'baz' => ['hi', 'there!'],
]);
// putForm() works as well

Exceptions

Invalid HTTP responses (status code 4xx or 5xx) will throw exceptions.

try {
    $http->get('https://example.com/api/products');
} catch (\GuzzleHttp\Exception\GuzzleException $e) {
    // $e->getRequest()
    // $e->getResponse()
    ...
}

Learn more.

Headers

$http = $http->withHeader('Authorization', "Bearer $token");

// Headers can have multiple values
$http = $http->withHeader('X-Foo', ['Bar', 'Baz']);

Timeouts

Timeouts are set at short values by default:

  • 5 seconds for the request timeout
  • 3 seconds for the HTTP connection timeout

You can set shorter or longer timeouts (or disable them by setting them at 0):

// 2 seconds for the request timeout, 1 second for the connection timeout
$http = $http->withTimeout(2, 1);

Query string parameters

You can set query string parameters in the request's URI:

$response = $http->get('http://httpbin.org?foo=bar');

You can specify the query string parameters as an array:

$http->withQueryParams(['foo' => 'bar'])
    ->get('http://httpbin.org');

Providing the option as an array will use PHP's http_build_query function to format the query string.

And finally, you can provide the query request option as a string.

$http->withQueryParams('foo=bar')
    ->get('http://httpbin.org');

Proxy

Use withSingleProxy() to specify a proxy for all protocols:

$http = $http->withSingleProxy('tcp://localhost:8125');

Use withMultipleProxies() to specify a different proxy for HTTP and HTTPS, as well as a list of host names that should not be proxied to:

$http = $http->withMultipleProxies(
    'tcp://localhost:8125', // Use this proxy with HTTP 
    'tcp://localhost:9124', // Use this proxy with HTTPS
    ['.mit.edu', 'foo.com'] // Don't use a proxy with these
);

Note that you can provide proxy URLs that contain a scheme, username, and password. For example, http://username:password@192.168.16.1:10.

Guzzle integration

Bof is based on Guzzle. You can even make it use your own Guzzle client, for example if you preconfigured it:

$guzzleClient = new GuzzleHttp\Client([
    'base_uri' => 'http://httpbin.org',
    'timeout'  => 2.0,
]);

$http = new Bof\Http($guzzleClient);

Learn more.

Our Mission

We want to make open source more sustainable. The entire platform was born from this and everything we do is in aid of this.

Interesting Articles

Thank you for checking out LiveTechHelper |
2025 © lth-dev incorporated

p-e622a1a2