Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Installation

composer require --dev mtk3d/http-vcr

You need two things:

  • PHP 8.2 or newer.
  • An HTTP client to wrap — whichever one your project already uses. Guzzle 7+, Symfony’s Psr18Client, php-http, Buzz: all of them work as they are, because all of them implement Psr\Http\Client\ClientInterface, which is the one thing http-vcr wraps.

That’s the whole list. To hand a recorded response back to your code, http-vcr also needs a factory that builds response objects — but it takes that from the HTTP client library you already have (Guzzle ships one, Symfony’s client pulls one in, and so on), so there is nothing extra to install, register, or pass in. In the unlikely case that nothing usable is found, http-vcr stops before the first request rather than partway through one, and composer require --dev nyholm/psr7 settles it. If you’d rather supply your own, see the VcrClient reference.

The record/replay core depends only on the PSR interfaces themselves (psr/http-message, psr/http-client, psr/http-factory, psr/clock) — no Guzzle, no Symfony, no framework. The package also pulls in symfony/console and nikic/php-parser, used exclusively by the CLI; since http-vcr is a dev dependency, those never reach a production autoloader.

Optional pieces

Install these only if needed:

PackageNeeded for
guzzlehttp/guzzleThe VcrMiddleware bridge for a Guzzle HandlerStack — plain GuzzleHttp\Client works without it
symfony/http-clientThe VcrHttpClient bridge for Symfony’s native HttpClientInterfacePsr18Client works without it
symfony/yamlThe YAML cassette serializer, for teams that would rather not use the default JSON one
phpunit/phpunitThe #[UseCassette] attribute and InteractsWithCassettes trait. The attribute is built on the Extension API, so the bridge supports PHPUnit 10 through 13 — http-vcr’s own test suite runs on 11.5–13, but that’s a separate matter from what the bridge supports in your project
mtk3d/laravel-http-vcrZero-setup use in a Laravel app — auto-registered service provider, Http facade interception, artisan vcr:* commands. A separate package that depends on this one; needs Laravel 11 or newer

See Framework Integration for details on each.

Using it with PHPUnit

One line in phpunit.xml registers the extension that powers #[UseCassette]:

<extensions>
    <bootstrap class="HttpVcr\Bridge\PHPUnit\Extension"/>
</extensions>

PHPUnit doesn’t discover extensions on its own, so without this the attribute has no effect at all — see PHPUnit Integration.

The CLI

Composer links the CLI into the consuming project’s vendor/bin:

vendor/bin/http-vcr providers

In a Laravel app the same commands are also available through artisan vcr:* — see the CLI Reference.

Where cassettes go

By default, tests/Cassettes/ relative to the project root (the directory containing composer.json), with the cassette name as a path inside it — shopify/get-product becomes tests/Cassettes/shopify/get-product.json. Change it with cassetteDirectory in http-vcr.php.

Cassettes are meant to be committed. The lock files http-vcr uses while recording are not, and take no setup either way: they go in a .http-vcr/ directory inside the cassette directory, which ignores itself.