当前位置:首页 > 娱乐

php查看curl请求的参数

调一个第三方接口,查参数对方说参数不对,请求你盯着自己写的查参数 curl_setopt 一行行看,越看越觉得没问题。请求这种时候别猜,查参数直接把最终发出去的请求请求打出来看。PHP 的查参数 cURL 扩展提供了几个钩子,能让你在请求真正发出前截获完整参数。请求

最直接的查参数办法是 CURLOPT_VERBOSE 配合 CURLOPT_STDERR。默认 verbose 信息会混在输出里,请求不好抓。查参数把它重定向到一个临时流,请求就能拿到干净的查参数调试日志:

$fp = fopen('php://temp', 'w+'); $ch = curl_init('https://api.example.com/v1/order'); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_POSTFIELDS => http_build_query(['id' => 42, 'sign' => 'abc']), CURLOPT_VERBOSE => true, CURLOPT_STDERR => $fp, CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); rewind($fp); $verbose = stream_get_contents($fp); fclose($fp); curl_close($ch); echo $verbose; 

这段日志里能看到请求行、请求头、请求以及 POST 的查参数 body。注意一点:如果 POSTFIELDS 传的是数组,cURL 会自动用 multipart/form-data 编码,日志里 body 部分会显示成一段段的分隔符,看起来有点乱,但参数都在。

verbose 有个坑——它不会把 CURLOPT_HTTPHEADER 里你手动设置的 header 和 cURL 自动加的 header 区分开,全混在一起。如果你要精确知道某个自定义 header 有没有生效,得换个思路。

CURLOPT_DEBUGFUNCTION 更灵活。它允许你注册一个回调,cURL 每产生一条调试信息就调用一次,你可以按类型过滤:

curl_setopt($ch, CURLOPT_DEBUGFUNCTION, function($ch, $type, $data) {  if ($type === CURLINFO_HEADER_OUT) {  echo "--- 发出的请求头 ---\n" . $data; } if ($type === CURLINFO_DATA_OUT) {  echo "--- 发出的 body ---\n" . $data; } return strlen($data); }); curl_setopt($ch, CURLOPT_VERBOSE, true); 

CURLINFO_HEADER_OUT 只在 VERBOSE 开启时才会触发,这点容易忘。回调里返回 strlen($data) 是约定,不返回或返回错会导致请求中断。

还有个小细节:CURLINFO_HEADER_OUT 拿到的 header 字符串末尾自带 \r\n,如果你要解析成数组,记得 trim 一下再 explode。我见过有人直接 explode("\n", $data),结果每行后面都挂个 \r,拿去匹配 header 名死活对不上。

如果不想改业务代码里的 cURL 调用,还有个偷懒的办法——用 curl_getinfo 在请求结束后看部分信息。CURLINFO_REQUEST_SIZE 能告诉你请求体字节数,CURLINFO_HEADER_OUT 在 curl_getinfo($ch, CURLINFO_HEADER_OUT) 里也能取到,但前提同样是开了 verbose。这个方式适合临时排查,不适合长期挂在代码里。

实际项目中我更推荐用 Guzzle 这类封装库,它的 on_stats 中间件能直接拿到 RequestInterface 对象,参数结构清清楚楚,不用跟 cURL 的底层日志较劲。但如果你维护的是老代码,或者就是不想引入依赖,上面这几个原生方法够用了。

最后提醒一句:调试信息里可能包含 API key、token、用户手机号这些敏感数据,别把 verbose 日志直接写进生产环境的日志文件。临时开、看完关,养成习惯。

分享到: