Skip to content

Instantly share code, notes, and snippets.

@drupol
Last active September 30, 2022 13:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save drupol/f6ffd5b616cce819dc454783b99132d5 to your computer and use it in GitHub Desktop.
Save drupol/f6ffd5b616cce819dc454783b99132d5 to your computer and use it in GitHub Desktop.
PSR responses issue when retrieving the body more than once
<?php
/**
* This snippet is failing.
*
* To reproduce it you need:
* - nyholm/psr7
* - symfony/http-client
*/
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use Nyholm\Psr7\Factory\Psr17Factory;
use Nyholm\Psr7\Stream;
use Symfony\Component\HttpClient\HttpClient;
use Symfony\Component\HttpClient\Response\StreamWrapper;
// Build Symfony HTTP client
$symfonyClient = HttpClient::create();
// Build Symfony HTTP response
$symfonyResponse = $symfonyClient->request('GET', 'https://chromedriver.storage.googleapis.com/LATEST_RELEASE');
// Build a PHP resource
$resource = StreamWrapper::createResource($symfonyResponse, $symfonyClient);
// Build a PSR response
$response = (new Psr17Factory)->createResponse(200)->withBody(Stream::create($resource));
// This works
dump('Symfony 1: ' . (string) $symfonyResponse->getContent()); // Works fine
dump('Symfony 2: ' . (string) $symfonyResponse->getContent()); // Works fine
// This almost works
dump('PSR 1: ' . (string) $response->getBody()); // Works fine
dump('PSR 2: ' . (string) $response->getBody()); // Does not work
// $response->getBody()->rewind(); // This throws an exception (Fatal error: Uncaught RuntimeException: Stream is not seekable)
// $response->getBody()->seek(0); // This throws an exception (Fatal error: Uncaught RuntimeException: Stream is not seekable)
<?php
/**
* This example works.
*
* To reproduce it you need:
* - nyholm/psr7
* - symfony/http-client
*/
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use Nyholm\Psr7\Factory\Psr17Factory;
use Nyholm\Psr7\Stream;
use Symfony\Component\HttpClient\HttpClient;
use Symfony\Component\HttpClient\Psr18Client;
// Build Symfony HTTP client
$symfonyClient = HttpClient::create();
// Build PSR http client
$psrClient = new Psr18Client($symfonyClient);
// Build PSR request
$request = (new Psr17Factory)->createRequest('GET', 'https://chromedriver.storage.googleapis.com/LATEST_RELEASE');
// Build PSR HTTP response
$psrResponse = $psrClient->sendRequest($request);
// This works
dump('PSR 1: ' . (string) $psrResponse->getBody()); // Works fine
dump('PSR 2: ' . (string) $psrResponse->getBody()); // Works fine
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment