有时候接口问题比较难调, 需要整个完整请求链路过程的记录. 有了请求报文和响应报文,就很好的定位问题. curl是支持打印出这些信息的, 很简单,一行配置搞定. 话不多说,直接上代码(将如下配置放在curl_exec前即可了)

$f = fopen('curl_debug', 'wb');
curl_setopt($ch,CURLOPT_VERBOSE,true);//默认是标准错误输出中
curl_setopt($ch,CURLOPT_STDERR ,$f);//有了该指令,请求过程记录会写到该文件中

文件中内容,大概是如下(本身输出内容是不包含响应body的,有需要你可自己追加在该文件后,便更好查看)

*   Trying 14.215.177.39...
* TCP_NODELAY set
* Connected to www.baidu.com (14.215.177.39) port 80 (#0)
> GET / HTTP/1.1
Host: www.baidu.com
Accept: */*

< HTTP/1.1 200 OK
< Accept-Ranges: bytes
< Cache-Control: no-cache
< Connection: keep-alive
< Content-Length: 14615
< Content-Type: text/html
< Date: Tue, 02 Nov 2021 16:34:39 GMT
< Pragma: no-cache
< Server: BWS/1.1
< Vary: Accept-Encoding
< 
* Connection #0 to host www.baidu.com left intact

ps: 有点需要注意, curl本身的bug,导致如果CURLINFO_HEADER_OUT设置为true时(即开启输出响应头), CURLOPT_VERBOSE会不生效.所以你需要将CURLINFO_HEADER_OUT配置去掉.

用这种方法不仅优雅,而且是最准确.像自己根据响应的换行去分隔会有不准确的情况发生.

$headers = [];
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

// this function is called by curl for each header received
curl_setopt($ch, CURLOPT_HEADERFUNCTION,
  function($curl, $header) use (&$headers)
  {
    $len = strlen($header);
    $header = explode(':', $header, 2);
    if (count($header) < 2) // ignore invalid headers
      return $len;

    $headers[strtolower(trim($header[0]))][] = trim($header[1]);

    return $len;
  }
);

$data = curl_exec($ch);
print_r($headers);

值得注意的点:

  • cli的opcache和php-fpm的opcache是独立的.(你可以自己实验下)这意味着,你在cli下使用opcache_reset()函数无法清除opcache缓存,因为想要清除php-fpm的opcache你需要通过http方式访问这个清除脚本, cli下执行这个函数只能清除cli的opcache. 此外,清除php-fpm的opcache还有个方法就是重启php-fpm也可.

curl基本语法:
curl [options...] <url>
options参数说明:
-A: 设置用户代理标头 curl -A 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36' https://google.com
-b: 设置cookie curl -b 'foo=bar' https://google.com
-d: 指定post请求发送的参数. 使用该参数, 请求头会默认加上Content-Type : application/x-www-form-urlencoded, 并使用POST方式请求. curl -d 'a=666' -d 'b=999' https://google.com
--data-urlencode: 与-d参数相同, 不过发送前会对参数进行urlencode.
-F: 上传文件. curl -F 'file=@photo.png' https://google.com 同时也可以指定文件名和MIME类型: curl -F 'file=@photo.png;filename=me.png;type=image/png' https://google.com 该请求,服务器会接收到名为me.png,类型为image/png格式的文件.
-G: 指定发送GET请求,并将由'-d, '--data-urlencode等选项指定的参数拼接在url后面, 而不是放在请求的body里.
-H: 指定请求头, post请求发送son请求: curl -d '{"login": "admin", "pass": "123"}' -H 'Content-Type: application/json' https://google.com/login
-i: 响应的数据中显示HTTP响应头
-L: 指定跟随服务器的重定向,默认不跟随
-o: 将服务器返回保存到指定文件 curl -o example.html https://www.example.com
-v: 显示整个通信过程,调试时很有用.会显示具体的请求体和响应体. --trace参数会显示更具体的二进制信息.
-x: 指定代理 curl -x 'http://username@password@127.0.0.1:80' https://www.example.com 使用127.0.0.1代理,并指定用户名和密码.
-X: 指定请求方法.curl -X POST https://www.example.com

常用场景下的例子: