Zend\Feed is a powerful library for discovering, reading and writing RSS feeds in various formats (we’re only interested in discovery and reading here). By default Zend\Feed\Reader\Reader, which is a collection of static methods to access feed reading and discovery functionality, uses a Zend\Http\Client to handle HTTP communication. Unfortunately Zend\Http\Client has some issues when being used in the wild, such as: “Incorrect handling of negative MaxAge cookie attribute” or “ChunkedBody decoding with Curl Adapter” or some others.
That’s why we tried to integrate Zend\Feed\Reader\Reader with a different HTTP client library that was already part of the project: Guzzle. Guzzle is a powerful HTTP client and it supports PSR-7 – the PHP-FIG standard for HTTP message interfaces. Based on this standard integration worked like a charm, because there is a hardly documented PSR-7 compatibility layer included in Zend\Feed\Reader – the Zend\Feed\Reader\Http\Psr7ResponseDecorator.
Integrating Guzzle into Zend\Feed\Reader\Reader just required one class though – an implementation of Zend\Feed\Reader\Http\ClientInterface which is one of the easiest interfaces you can think of:
namespace Zend\Feed\Reader\Http;
interface ClientInterface
{
/**
* Make a GET request to a given URI
*
* @param string $uri
* @return ResponseInterface
*/
public function get($uri);
}
Our AppBundle\Feed\GuzzleClient turned out to be as simple as:
namespace AppBundle\Feed;
use GuzzleHttp\Client;
use GuzzleHttp\ClientInterface as GuzzleClientInterface;
use Zend\Feed\Reader\Http\ClientInterface as FeedReaderHttpClientInterface;
use Zend\Feed\Reader\Http\Psr7ResponseDecorator;
/**
* Class GuzzleClient
*
* @package AppBundle\Feed
*/
class GuzzleClient implements FeedReaderHttpClientInterface
{
/**
* @var GuzzleClientInterface
*/
private $client;
/**
* GuzzleClient constructor.
*
* @param GuzzleClientInterface|null $client
*/
public function __construct(GuzzleClientInterface $client = null)
{
$this->client = $client ?: new Client();
}
/**
* {@inheritdoc}
*/
public function get($uri)
{
$response = $this->client->request('GET', $uri);
return new Psr7ResponseDecorator($response);
}
}
GuzzleHttp\ClientInterface::request() returns a Psr\Http\Message\ResponseInterface which can directly be put into an instance of Zend\Feed\Reader\Http\Psr7ResponseDecorator.
Now we could just replace Zend\Feed\Reader\Reader‘s HTTP client with our new Guzzle decorator:
Zend\Feed\Reader\Reader::setHttpClient(new AppBundle\Feed\GuzzleClient());
That’s it – feed discovery (Zend\Feed\Reader\Reader::findFeedLinks($uri)) and feed reading (Zend\Feed\Reader\Reader::import($uri)) now communicate via the more robust Guzzle library instead of Zend\Http\Client.[/fusion_builder_column][/fusion_builder_row][/fusion_builder_container]
