方法
<?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_NONE, // HTTP版本
];
// 合并默认设置和用户自定义设置
$options = array_merge($defaults, $options);
// 设置请求方法
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $options['method']);
// 设置头部
if (!empty($options['headers'])) {
curl_setopt($ch, CURLOPT_HTTPHEADER, $options['headers']);
}
// 构建multipart/form-data请求体
if (!is_null($options['body']) && is_array($options['body'])) {
$boundary = '--------------------------'.microtime(true);
$body = build_multipart_formdata($options['body'], $boundary);
array_push($options['headers'], "Content-Type: multipart/form-data; boundary=$boundary");
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
} 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,
];
}
/**
* 构建multipart/form-data请求体
*
* @param array $pairs 键值对数组
* @param string $boundary 分界符
* @return string 构建好的请求体
*/
function build_multipart_formdata($pairs, $boundary) {
$body = '';
foreach ($pairs as $key => $value) {
$body .= "--$boundary\r\n";
if ($value instanceof CURLFile) {
$body .= "Content-Disposition: form-data; name=\"$key\"; filename=\"{$value->name}\"\r\n";
$body .= "Content-Type: {$value->type}\r\n\r\n";
$body .= $value->open()->fread($value->getSize()) . "\r\n";
} else {
$body .= "Content-Disposition: form-data; name=\"$key\"\r\n\r\n";
$body .= "$value\r\n";
}
}
$body .= "--$boundary--\r\n";
return $body;
}
使用
发送JSON格式的请求
$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格式的请求
$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格式的请求(通常用于文件上传)
$url = 'http://example.com/upload'; // 目标URL
$form_data = [
'field1' => 'value1', // 表单字段
'field2' => 'value2',
'file' => new CURLFile('/path/to/file.jpg', 'image/jpeg', 'file.jpg'), // 文件
];
$response = JT_curl($url, [
'method' => 'POST',
'body' => $form_data, // 表单数据和文件
]);
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
: 完成请求所需的总时间,单位是微秒。