256 lines
13 KiB
PHP
256 lines
13 KiB
PHP
<?php
|
|
// +----------------------------------------------------------------------
|
|
// | YwxApp [ WE CAN DO IT JUST THINK ]
|
|
// +----------------------------------------------------------------------
|
|
// | Copyright (c) 2026-2036 http://ywxapp.cn All rights reserved.
|
|
// +----------------------------------------------------------------------
|
|
// | Author: ywxapp<admin@ywxapp.cn>
|
|
// +----------------------------------------------------------------------
|
|
|
|
namespace ywxapp\utils;
|
|
|
|
/**
|
|
* HttpClient - PHP HTTP请求工具类
|
|
* 封装cURL操作,简化HTTP请求过程。
|
|
*/
|
|
class HttpClient
|
|
{
|
|
/**
|
|
* cURL句柄
|
|
* @var resource
|
|
*/
|
|
private $ch;
|
|
|
|
/**
|
|
* 默认配置选项
|
|
* @var array
|
|
*/
|
|
private $defaultOptions = [
|
|
CURLOPT_RETURNTRANSFER => true, // 将响应作为字符串返回
|
|
CURLOPT_FOLLOWLOCATION => true, // 跟随重定向
|
|
CURLOPT_MAXREDIRS => 5, // 最大重定向次数
|
|
CURLOPT_TIMEOUT => 30, // 整体请求超时时间(秒)
|
|
CURLOPT_CONNECTTIMEOUT => 10, // 连接超时时间(秒)
|
|
CURLOPT_USERAGENT => 'HttpClient/1.0 (PHP)', // 默认User-Agent
|
|
CURLOPT_SSL_VERIFYPEER => true, // 验证SSL证书
|
|
CURLOPT_SSL_VERIFYHOST => 2, // 验证SSL主机名
|
|
];
|
|
|
|
/**
|
|
* 构造函数,初始化cURL会话。
|
|
* @param string|null $url 初始URL,可选。
|
|
*/
|
|
public function __construct(?string $url = null)
|
|
{
|
|
$this->ch = curl_init($url);
|
|
curl_setopt_array($this->ch, $this->defaultOptions);
|
|
}
|
|
|
|
/**
|
|
* 设置单个cURL选项。
|
|
* @param int $option CURLOPT_* 常量。
|
|
* @param mixed $value 选项值。
|
|
* @return self 返回当前实例以支持链式调用。
|
|
*/
|
|
public function setOption(int $option, $value): self
|
|
{
|
|
curl_setopt($this->ch, $option, $value);
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* 批量设置cURL选项。
|
|
* @param array $options 选项键值对数组。
|
|
* @return self 返回当前实例以支持链式调用。
|
|
*/
|
|
public function setOptions(array $options): self
|
|
{
|
|
curl_setopt_array($this->ch, $options);
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* 设置请求URL。
|
|
* @param string $url 请求的目标URL。
|
|
* @return self 返回当前实例以支持链式调用。
|
|
*/
|
|
public function setUrl(string $url): self
|
|
{
|
|
return $this->setOption(CURLOPT_URL, $url);
|
|
}
|
|
|
|
/**
|
|
* 设置自定义HTTP请求头。
|
|
* @param array $headers 头信息数组,例如 ['Content-Type: application/json']。
|
|
* @return self 返回当前实例以支持链式调用。
|
|
*/
|
|
public function setHeaders(array $headers): self
|
|
{
|
|
return $this->setOption(CURLOPT_HTTPHEADER, $headers);
|
|
}
|
|
|
|
/**
|
|
* 设置Cookie字符串或文件。
|
|
* @param string|null $cookie Cookie字符串,如 "name=value; path=/".
|
|
* @param string|null $cookieFile 发送请求时使用的Cookie文件路径。
|
|
* @param string|null $cookieJar 接收响应后保存Cookie的文件路径。
|
|
* @return self 返回当前实例以支持链式调用。
|
|
*/
|
|
public function setCookie(?string $cookie = null, ?string $cookieFile = null, ?string $cookieJar = null): self
|
|
{
|
|
if ($cookie !== null) {
|
|
$this->setOption(CURLOPT_COOKIE, $cookie);
|
|
}
|
|
if ($cookieFile !== null && is_file($cookieFile)) {
|
|
$this->setOption(CURLOPT_COOKIEFILE, $cookieFile);
|
|
}
|
|
if ($cookieJar !== null) {
|
|
$this->setOption(CURLOPT_COOKIEJAR, $cookieJar);
|
|
}
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* 执行GET请求。
|
|
* @param string $url 请求URL。
|
|
* @param array|string|null $queryParams GET查询参数,数组或已编码字符串。
|
|
* @return string|false 成功返回响应体,失败返回false。
|
|
*/
|
|
public function get(string $url, $queryParams = null)
|
|
{
|
|
$this->setUrl($url);
|
|
$this->setOption(CURLOPT_HTTPGET, true);
|
|
|
|
if ($queryParams !== null) {
|
|
if (is_array($queryParams)) {
|
|
$queryString = http_build_query($queryParams);
|
|
} else {
|
|
$queryString = $queryParams;
|
|
}
|
|
$currentUrl = curl_getinfo($this->ch, CURLINFO_EFFECTIVE_URL);
|
|
$this->setUrl($currentUrl . (strpos($currentUrl, '?') === false ? '?' : '&') . $queryString);
|
|
}
|
|
|
|
return $this->execute();
|
|
}
|
|
|
|
/**
|
|
* 执行POST请求。
|
|
* @param string $url 请求URL。
|
|
* @param array|string $postData POST数据,数组或已编码字符串。
|
|
* @return string|false 成功返回响应体,失败返回false。
|
|
*/
|
|
public function post(string $url, $postData)
|
|
{
|
|
$this->setUrl($url);
|
|
$this->setOption(CURLOPT_POST, true);
|
|
$this->setOption(CURLOPT_POSTFIELDS, $postData);
|
|
return $this->execute();
|
|
}
|
|
|
|
/**
|
|
* 执行PUT请求。
|
|
* @param string $url 请求URL。
|
|
* @param array|string $putData PUT数据。
|
|
* @return string|false 成功返回响应体,失败返回false。
|
|
*/
|
|
public function put(string $url, $putData)
|
|
{
|
|
$this->setUrl($url);
|
|
$this->setOption(CURLOPT_CUSTOMREQUEST, 'PUT');
|
|
$this->setOption(CURLOPT_POSTFIELDS, $putData);
|
|
return $this->execute();
|
|
}
|
|
|
|
/**
|
|
* 执行DELETE请求。
|
|
* @param string $url 请求URL。
|
|
* @return string|false 成功返回响应体,失败返回false。
|
|
*/
|
|
public function delete(string $url)
|
|
{
|
|
$this->setUrl($url);
|
|
$this->setOption(CURLOPT_CUSTOMREQUEST, 'DELETE');
|
|
return $this->execute();
|
|
}
|
|
|
|
/**
|
|
* 执行配置好的cURL请求。
|
|
* @return string|false 成功返回响应体,失败返回false。
|
|
*/
|
|
private function execute()
|
|
{
|
|
$response = curl_exec($this->ch);
|
|
return $response;
|
|
}
|
|
|
|
/**
|
|
* 获取最后一次请求的HTTP状态码。
|
|
* @return int HTTP状态码。
|
|
*/
|
|
public function getStatusCode(): int
|
|
{
|
|
return curl_getinfo($this->ch, CURLINFO_HTTP_CODE);
|
|
}
|
|
|
|
/**
|
|
* 获取最后一次请求的错误信息。
|
|
* @return string 错误信息,无错误时返回空字符串。
|
|
*/
|
|
public function getError(): string
|
|
{
|
|
return curl_error($this->ch);
|
|
}
|
|
|
|
/**
|
|
* 获取最后一次请求的错误码。
|
|
* @return int cURL错误码。
|
|
*/
|
|
public function getErrno(): int
|
|
{
|
|
return curl_errno($this->ch);
|
|
}
|
|
|
|
/**
|
|
* 获取最后一次请求的详细信息(curl_getinfo)。
|
|
* @param int|null $opt 特定的CURLINFO_*常量,为null则返回全部信息。
|
|
* @return mixed 详细信息。
|
|
*/
|
|
public function getInfo(?int $opt = null)
|
|
{
|
|
if ($opt === null) {
|
|
return curl_getinfo($this->ch);
|
|
}
|
|
return curl_getinfo($this->ch, $opt);
|
|
}
|
|
|
|
/**
|
|
* 重置cURL会话至默认状态,便于复用。
|
|
* @return self 返回当前实例以支持链式调用。
|
|
*/
|
|
public function reset(): self
|
|
{
|
|
curl_reset($this->ch);
|
|
curl_setopt_array($this->ch, $this->defaultOptions);
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* 析构函数,关闭cURL句柄释放资源。
|
|
*/
|
|
public function __destruct()
|
|
{
|
|
if (is_resource($this->ch)) {
|
|
curl_close($this->ch);
|
|
}
|
|
}
|
|
}
|
|
|
|
// $client = new HttpClient();
|
|
// $params = ['page' => 1, 'limit' => 20];
|
|
// $response =
|
|
|
|
// :::ml-data{name=citationList}
|
|
// ```json
|
|
// [{"source":{"logo":"https://ss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=2005731947,4139443793&fm=195&app=88&f=JPEG?w=200&h=200","name":"CSDN博客"},"isVideo":false,"title":"PHP中高效HTTP请求工具封装与实战-CSDN博客","thumbnail":"http://t9.baidu.com/it/u=2017426770,2814227408&fm=217&app=126&f=JPEG?w=799&h=413&s=29F2E3040BB1844D5CD52401000070C0","linkInfo":{"data-click-info":"{}","href":"https://blog.csdn.net/weixin_33481022/article/details/151726962","target":"_blank","data-noblank":true,"data-show":"list","data-show-ext":"{\"pos\":\"1\",\"component_content\":{\"component_name\":\"reference\"}}"}},{"source":{"logo":"https://ss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=2005731947,4139443793&fm=195&app=88&f=JPEG?w=200&h=200","name":"CSDN博客"},"isVideo":false,"title":"PHP CURL HTTP请求类实现","thumbnail":"http://t9.baidu.com/it/u=1357407678,4243128088&fm=217&app=126&f=JPEG?w=800&h=317&s=EF70A15603604D2204ECA1DA030090B2","linkInfo":{"data-click-info":"{}","href":"https://blog.csdn.net/weixin_35756892/article/details/149955066","target":"_blank","data-noblank":true,"data-show":"list","data-show-ext":"{\"pos\":\"2\",\"component_content\":{\"component_name\":\"reference\"}}"}},{"source":{"logo":"https://ss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=2005731947,4139443793&fm=195&app=88&f=JPEG?w=200&h=200","name":"CSDN博客"},"isVideo":false,"title":"php request 类型,PHP Request工具类","linkInfo":{"data-click-info":"{}","href":"https://blog.csdn.net/weixin_39616416/article/details/115761125","target":"_blank","data-noblank":true,"data-show":"list","data-show-ext":"{\"pos\":\"3\",\"component_content\":{\"component_name\":\"reference\"}}"}},{"source":{"logo":"https://ss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=2005731947,4139443793&fm=195&app=88&f=JPEG?w=200&h=200","name":"CSDN博客"},"isVideo":false,"title":"PHP中基于cURL的CurlUtils工具类实战应用","linkInfo":{"data-click-info":"{}","href":"https://blog.csdn.net/weixin_42153793/article/details/154161833","target":"_blank","data-noblank":true,"data-show":"list","data-show-ext":"{\"pos\":\"4\",\"component_content\":{\"component_name\":\"reference\"}}"}},{"source":{"logo":"https://ss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=2005731947,4139443793&fm=195&app=88&f=JPEG?w=200&h=200","name":"CSDN博客"},"isVideo":false,"title":"推荐文章:PHP的Curl客户端库 —— 灵活高效的HTTP请求处理工具","linkInfo":{"data-click-info":"{}","href":"https://blog.csdn.net/gitblog_00057/article/details/139112125","target":"_blank","data-noblank":true,"data-show":"list","data-show-ext":"{\"pos\":\"5\",\"component_content\":{\"component_name\":\"reference\"}}"}},{"source":{"logo":"https://ss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=2005731947,4139443793&fm=195&app=88&f=JPEG?w=200&h=200","name":"CSDN博客"},"isVideo":false,"title":"php的httprequest类,PHP http抓取类 HttpRequest","linkInfo":{"data-click-info":"{}","href":"https://blog.csdn.net/weixin_42363854/article/details/115883717","target":"_blank","data-noblank":true,"data-show":"list","data-show-ext":"{\"pos\":\"6\",\"component_content\":{\"component_name\":\"reference\"}}"}},{"source":{"name":"PHP官网"},"isVideo":false,"title":"The EventHttpRequest class ¶","linkInfo":{"data-click-info":"{}","href":"https://www.php.net/manual/ja/class.eventhttprequest.php","target":"_blank","data-noblank":true,"data-show":"list","data-show-ext":"{\"pos\":\"7\",\"component_content\":{\"component_name\":\"reference\"}}"}},{"source":{"name":"php中文网"},"isVideo":false,"title":"php工具如何使用CURL进行HTTP请求_php工具网络通信的实用技巧","thumbnail":"http://t7.baidu.com/it/u=3190634218,2722667569&fm=217&app=126&f=JPEG?w=650&h=374&s=6171A36449932CC2477B3F8B0300A09C","linkInfo":{"data-click-info":"{}","href":"https://www.php.cn/faq/1721770.html","target":"_blank","data-noblank":true,"data-show":"list","data-show-ext":"{\"pos\":\"8\",\"component_content\":{\"component_name\":\"reference\"}}"}},{"source":{"logo":"https://ss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=2005731947,4139443793&fm=195&app=88&f=JPEG?w=200&h=200","name":"CSDN博客"},"isVideo":false,"title":"【PHP HTTP客户端实战指南】:掌握Guzzle与cURL高效请求技巧","linkInfo":{"data-click-info":"{}","href":"https://blog.csdn.net/QuickSolve/article/details/153877227","target":"_blank","data-noblank":true,"data-show":"list","data-show-ext":"{\"pos\":\"9\",\"component_content\":{\"component_name\":\"reference\"}}"}},{"source":{"name":"CRMEB官网"},"isVideo":false,"title":"php request 类型,PHP Request工具类-CRMEB社区","linkInfo":{"data-click-info":"{}","href":"https://www.crmeb.com/ask/thread/22750","target":"_blank","data-noblank":true,"data-show":"list","data-show-ext":"{\"pos\":\"10\",\"component_content\":{\"component_name\":\"reference\"}}"}},{"source":{"name":"PHP官网"},"isVideo":false,"title":"The Swoole\\Http\\Request class","linkInfo":{"data-click-info":"{}","href":"https://www.php.net/swoole-http-request","target":"_blank","data-noblank":true,"data-show":"list","data-show-ext":"{\"pos\":\"11\",\"component_content\":{\"component_name\":\"reference\"}}"}},{"source":{"name":"PHP官网"},"isVideo":false,"title":"The Yaf_Request_Http class ¶","linkInfo":{"data-click-info":"{}","href":"https://www.php.net/manual/zh/class.yaf-request-http.php","target":"_blank","data-noblank":true,"data-show":"list","data-show-ext":"{\"pos\":\"12\",\"component_content\":{\"component_name\":\"reference\"}}"}}]
|