一个较为完整的PHP cURL封装方法-JT_curl

2024-09-01 15:15:26 浏览数 (2)

方法

代码语言:txt复制
<?php

/**
 * JT_curl - 一个PHP cURL封装方法
 * 
 * @author 岳泽以
 * @date 2024年9月1日15:00:00
 * @param string $url 请求的URL
 * @param array $options 请求参数
 * @return mixed
 */
function JT_curl($url, $options = [])
{
  // 初始化cURL会话
  $ch = curl_init($url);

  // 默认设置
  $defaults = [
    'method' => 'GET', // 请求方法
    'headers' => [], // 自定义头部
    'body' => null, // 请求体
    'timeout' => 30, // 超时时间
    'connect_timeout' => 30, // 连接超时时间
    'follow_location' => true, // 是否跟随重定向
    'max_redirects' => 5, // 最大重定向次数
    'return_transfer' => true, // 是否返回响应内容
    'encoding' => 'gzip', // 响应编码
    'user_agent' => 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36', // 用户代理
    'ssl_verify_peer' => false, // 是否验证SSL证书
    'ssl_verify_host' => false, // 是否验证SSL证书的主机名
    'cookie' => null, // Cookie
    'referer' => null, // 引用页
    'http_version' => CURL_HTTP_VERSION_1_1, // HTTP版本
  ];

  // 合并默认设置和用户自定义设置
  $options = array_merge($defaults, $options);

  // 设置请求方法
  curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $options['method']);

  // 设置头部
  if (!empty($options['headers'])) {
    curl_setopt($ch, CURLOPT_HTTPHEADER, $options['headers']);
  }

  // 设置请求体
  if (!is_null($options['body'])) {
    if (is_array($options['body'])) {
      if (isset($options['body'][CURLOPT_POSTFIELDS])) {
        curl_setopt($ch, CURLOPT_POSTFIELDS, $options['body'][CURLOPT_POSTFIELDS]);
      } else {
        $multipart = [];
        foreach ($options['body'] as $key => $value) {
          if ($value instanceof CURLFile) {
            // 构建 multipart/form-data 格式
            $multipart[] = "{$key}=" . $value->name;
          } else {
            $multipart[] = "{$key}=" . urlencode($value);
          }
        }
        curl_setopt($ch, CURLOPT_POSTFIELDS, implode('&', $multipart));
        curl_setopt($ch, CURLOPT_HTTPHEADER, array_merge($options['headers'], ['Content-Type: multipart/form-data']));
      }
    } else {
      curl_setopt($ch, CURLOPT_POSTFIELDS, $options['body']);
    }
  }

  // 设置超时
  curl_setopt($ch, CURLOPT_TIMEOUT, $options['timeout']);
  curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $options['connect_timeout']);

  // 设置是否跟随重定向
  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, $options['follow_location']);
  curl_setopt($ch, CURLOPT_MAXREDIRS, $options['max_redirects']);

  // 设置返回传输
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, $options['return_transfer']);

  // 设置响应编码
  curl_setopt($ch, CURLOPT_ENCODING, $options['encoding']);

  // 设置用户代理
  curl_setopt($ch, CURLOPT_USERAGENT, $options['user_agent']);

  // 设置SSL证书验证
  curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $options['ssl_verify_peer']);
  curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, $options['ssl_verify_host']);

  // 设置Cookie
  if (!is_null($options['cookie'])) {
    curl_setopt($ch, CURLOPT_COOKIE, $options['cookie']);
  }

  // 设置引用页
  if (!is_null($options['referer'])) {
    curl_setopt($ch, CURLOPT_REFERER, $options['referer']);
  }

  // 设置HTTP版本
  curl_setopt($ch, CURLOPT_HTTP_VERSION, $options['http_version']);

  // 执行cURL请求
  $response = curl_exec($ch);

  // 检查是否有错误发生
  if (curl_errno($ch)) {
    $error_msg = curl_error($ch);
    curl_close($ch);
    throw new Exception("cURL Error: {$error_msg}");
  }

  // 获取信息
  $info = curl_getinfo($ch);

  // 关闭cURL会话
  curl_close($ch);

  // 返回响应内容和信息
  return [
    'body' => $response,
    'info' => $info,
  ];
}

使用

发送JSON格式的请求

代码语言:javascript复制
$response = JT_curl('https://www.yuezeyi.com/api', [
    'method' => 'POST',
    'headers' => [
        'Content-Type: application/json',
    ],
    'body' => json_encode(['key' => 'value']),
]);

echo $response['body'];

发送form-data格式的请求

代码语言:javascript复制
$response = JT_curl('https://www.yuezeyi.com/api', [
    'method' => 'POST',
    'headers' => [
        'Content-Type: application/x-www-form-urlencoded',
    ],
    'body' => http_build_query(['key' => 'value']),
]);

echo $response['body'];

发送multipart/form-data格式的请求(通常用于文件上传)

代码语言:javascript复制
$response = JT_curl('https://www.yuezeyi.com/api', [
    'method' => 'POST',
    'body' => [
        'user' => 'username',
        'avatar' => new CURLFile('/path/to/avatar.jpg', 'image/jpeg', 'avatar.jpg'),
    ],
]);

echo $response['body'];

结果

完整结果为响应内容body和请求信息info

info内各字段解释:
  • url: 请求的 URL。
  • content_type: 响应的内容类型,这里是 application/json,表示返回的数据格式是 JSON。
  • http_code: HTTP 响应码,200 表示请求成功。
  • header_size: HTTP 响应头部的大小,单位是字节。
  • request_size: 请求的大小,包括头部和数据,单位是字节。
  • filetime: 文件修改时间,如果是 -1 表示没有文件修改时间可用。
  • ssl_verify_result: SSL 证书验证结果,20 表示证书是由一个可信的 CA 签发的,但可能存在其他问题(例如证书不是为这个特定的主机名签发的)。
  • redirect_count: 请求重定向的次数。
  • total_time: 完成请求所需的总时间,单位是秒。
  • namelookup_time: DNS 查找耗时,单位是秒。
  • connect_time: 建立服务器连接所需的时间,单位是秒。
  • pretransfer_time: 开始传输前的总时间,单位是秒。
  • size_upload: 上传的数据量,单位是字节。
  • size_download: 下载的数据量,单位是字节。
  • speed_download: 下载速度,单位是字节/秒。
  • speed_upload: 上传速度,单位是字节/秒。
  • download_content_length: 预期下载的内容长度,-1 表示未知或不适用。
  • upload_content_length: 预期上传的内容长度,单位是字节。
  • starttransfer_time: 开始传输数据所需的总时间,单位是秒。
  • redirect_time: 执行重定向所需的总时间,如果没有重定向则为 0。
  • redirect_url: 重定向的 URL,如果没有重定向则为空。
  • primary_ip: 服务器的 IP 地址。
  • certinfo: SSL 证书信息,通常包含证书的主题、颁发者、过期时间等。
  • primary_port: 服务器的端口号。
  • local_ip: 本地机器的 IP 地址。
  • local_port: 本地机器的端口号。
  • http_version: HTTP 协议版本,2 表示 HTTP/2。
  • protocol: 协议版本,2 表示使用了 SSL/TLS 的 HTTP/2。
  • ssl_verifyresult: SSL 证书验证结果,0 表示验证成功。
  • scheme: 使用的协议方案,"HTTPS" 表示使用了 SSL 加密的 HTTPS。
  • appconnect_time_us: 应用层连接建立所需的时间,单位是微秒。
  • connect_time_us: 建立服务器连接所需的时间,单位是微秒。
  • namelookup_time_us: DNS 查找耗时,单位是微秒。
  • pretransfer_time_us: 开始传输前的总时间,单位是微秒。
  • redirect_time_us: 执行重定向所需的总时间,单位是微秒。
  • starttransfer_time_us: 开始传输数据所需的总时间,单位是微秒。
  • total_time_us: 完成请求所需的总时间,单位是微秒。

0 人点赞