This article was peer reviewed by Márk Sági-Kazár. Thanks to all of SitePoint’s peer reviewers for making SitePoint content the best it can be!

In a previous series, we built a PHP client for Diffbot. The client works well and is in relatively widespread use – we even tested it on a live app to make sure it’s up to par – but it depends heavily on Guzzle 5.

There are two problems with this:

  1. Guzzle 6 is out, and supports PSR 7. While the author of Guzzle claims Guzzle 5 will be supported for the foreseeable future, it’s safer to be skeptical of its longevity. Besides, while PSR 7 might have its quirks, it’s good to follow PSRs if only for the compatibility with other projects
  2. Someone implementing our client in their app might already have a preferred HTTP client in use, and would like to use theirs rather than Guzzle. We should allow for easy injection of any HTTP client into our SDK.

Coincidentally, there is a new project allowing us to do just that: HTTPlug.

Travel power adapter

Note: you don’t need to be familiar with the internal logic of the Diffbot SDK to follow along. The process in this article is applicable to any package with a concrete HTTP Client implementation and is easy to follow.

PHP-HTTP and HTTPlug

PHP-HTTP is a Github organization and, among other things, a collection of adapters for various HTTP clients. On top of all these sits a common implementation in the form of a virtual package, named php-http/client-implementation, concretely realized by the collection of interfaces and exceptions presented in the HTTPlug sub-project.

The various adapters declare themselves as providers of this package, so someone who uses Guzzle 6 can composer require php-http/guzzle6-adapter, and this would pull in the adapter, the HTTPlug interface package, and Guzzle 6 itself as a dependency of the adapter.

HTTPlug is the entry point for a reusable package. It is the client abstraction all clients (like the Guzzle6 Adapter) are based on. These clients then further make use of their underlying packages / dependencies – Guzzle 6 in this case.

So, bottom to top:

  • an HTTP Client exists (Guzzle 6)
  • a Guzzle 6 adapter is built with HTTPlug as the interface for it, wraps Guzzle 6
  • an app needing to be able to make HTTP calls needs a client, requires HTTPlug’s HttpClient interface rather than Guzzle 6 directly
  • the app can then use Guzzle 6, or any other adapter implementing HTTPlug’s HttpClient interface and wrapping another third party HTTP Client

The team’s plan is to eventually have maximum support for all the various HTTP clients in PHP land: Guzzle 6, Guzzle 5, Zend2, Zend1, etc. That way, a user of a framework or app will have no conflicts with installed client versions, and will simply plug the appropriate adapter into the mix.

Note that we use the terms adapter and client here almost interchangeably – the adapters based on HTTPlug are both. They are wrappers around existing clients, but used directly as clients themselves.

Our plan in this post is to replace the concrete Guzzle 5 dependency of Diffbot’s PHP client with the HTTPlug version.

Note: HTTPlug and related packages are alpha software, and as such are subject to change. Converting anything to use them is a risky endeavor.

Bootstrapping

As usual, it’s recommended we use Homestead Improved to bootstrap our environment. Once we’re ready, we can clone and test the current stable version of the SDK:

git clone https://github.com/swader/diffbot-php-client
cd diffbot-php-client 
git checkout tags/0.4.5 
composer install
phpunit

The last command assumes PHPUnit is globally installed on the development environment.

All tests should pass (except for a skipped one that’s bugged and unfixable due to some nonsense), so we’re ready to begin the conversion.

Getting Started

First, we’ll need to create a new branch on which to develop this upgrade.

git checkout -b feature-httplug

Then, we add two dependencies into our composer.json file:

	"require": {
        ...
        "php-http/client-implementation": "^1.0"
    },
    "require-dev": {
        ...
        "php-http/guzzle6-adapter": "~0.2@dev"
    },

What this does is tell the client that from now on, it depends on a virtual packagethis one. This means that in order to be used, the application using our Diffbot client (like this one) must select an implementation of this package (one of those listed at the link on Packagist). Of course, during development of the package, it would be impossible to test and see if everything’s working without an actual implementation, so we specify an additional require-dev dependency. In the specific case above, we use "php-http/guzzle6-adapter": "~0.2@dev". We chose that particular version simply because it’s the newest one and there’s no stable release.

Note: You may be wondering why we used the approach of adding values into composer.json rather than declaring dependencies interactively in the terminal like we usually do. This is because doing a composer require on a virtual package will throw an error – the package doesn’t really exist, it’s just its virtual name, a placeholder, so Composer will get confused not knowing what to install. There is an issue suggesting a change to this, but it’s not likely to happen soon.

Since the php-http packages are still under heavy development, we should add the following two values to our composer.json file:

"prefer-stable": true,
"minimum-stability": "dev"

Continue reading %Breaking Free from Guzzle5 with PHP-HTTP and HTTPlug%

Source: SitePoint