php-vcr 是一个独立的 php 测试库,需通过 composer 安装并配置 autoload-dev 才能使用;它通过拦截 curl 函数实现 http 请求录制与回放,要求每个测试方法隔离 cassette 且仅支持 curl 及适配后的 guzzle。

PHP-VCR 是什么,它和 Composer 有什么关系
PHP-VCR 不是 Composer 的插件或扩展,而是一个独立的 PHP 库,需要通过 Composer 安装并加载。它本身不修改 Composer 行为,但依赖 Composer 的自动加载机制才能在测试中被 require 或 use。如果你执行 composer install 后在测试里 new VCRVCR() 报错 Class not found,大概率是没加 autoload-dev 配置,或者没在测试文件顶部正确引入命名空间。
安装时必须启用 dev-autoloader 并确认 autoloading 生效
PHP-VCR 只应在测试环境中使用,所以不能放到 "require",必须放在 "require-dev"。但更重要的是:它的类路径默认不在 PSR-4 自动映射范围内,需要显式声明 autoload-dev 规则,否则 phpunit 找不到 VCRVCR 类。
- 在
composer.json的"autoload-dev"下添加:"psr-4": { "VCR\": "vendor/php-vcr/php-vcr/src/VCR/" } - 运行
composer dump-autoload -o(加-o强制优化,避免测试时因 autoloader 缓存未更新导致类找不到) - 验证是否生效:在测试文件开头写
var_dump(class_exists('VCRVCR'));,输出true才算成功
录制与回放必须配对使用 VCR::turnOn() / VCR::turnOff(),且不能跨 test method 复用 cassette
PHP-VCR 的 cassette(磁带)是按测试方法隔离的。同一个 cassette 文件被多个 testXXX() 方法读写,会导致内容被覆盖或解析失败——不是报错,而是回放时匹配不到请求,悄悄退回到真实 HTTP 请求,测试就“看似通过实则没测”。
- 每个测试方法开头调用
VCR::turnOn(),结尾调用VCR::turnOff()(建议用tearDown()统一关) - cassette 名称建议包含测试方法名,例如:
VCR::insertCassette('test_api_fetch_user_success'); - 第一次运行时会录制到
fixtures/vcr/cassettes/...;后续运行直接读取,不再发真实请求 - 如果修改了被测代码中的请求 URL、method 或 body,必须手动删掉对应 cassette 文件,否则回放旧数据,测试失去意义
HTTP client 兼容性取决于底层 handler,cURL 和 Guzzle 默认支持,Guzzle 7+ 需额外适配
PHP-VCR 通过 patch PHP 的 cURL 扩展函数(如 curl_exec)实现拦截,因此原生 cURL 调用天然支持。但现代项目多用 Guzzle,而 Guzzle 6 使用 cURL handler,Guzzle 7+ 默认改用 ext-curl 或 ext-http,部分场景需手动指定 handler 才能被 VCR 拦截。
- Guzzle 6:无需额外配置,
new Client()即可被 VCR 拦截 - Guzzle 7+:必须显式传入 cURL handler:
$client = new Client(['handler' => GuzzleHttpHandlerCurlHandler::class]);
- 若用
file_get_contents()或stream_context_create()发请求,PHP-VCR 默认不拦截——它只 hook cURL 函数,不 patch stream wrappers
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











