HTTP请求类库封装分享,因为最近项目涉及到异步的请求 我加上了
封装优点:
1.简单的可以发送各种请求
2.可以发送异步的各种请求
3.请求的时候 创建 实例的时候 都可以修改 各项参数
4.提供单例模式,可以在某个方法内如果多次请求的话,可以共享cookies等信息
<?php
namespace App\Services;
use GuzzleHttp\Client;
use GuzzleHttp\Promise;
use GuzzleHttp\Promise\PromiseInterface;
use Psr\Http\Message\ResponseInterface;
/**
* HttpClient类 - HTTP请求客户端工具
*
* 基于GuzzleHttp封装的HTTP客户端,支持同步和异步请求,
* 提供单例模式和链式调用,简化HTTP请求操作
*/
class HttpClient
{
/**
* @var HttpClient|null $instance 单例模式的静态实例
*/
private static $instance = null;
/**
* @var Client $client Guzzle HTTP客户端实例
*/
private $client;
/**
* @var array $headers 全局请求头设置
*/
private $headers = [];
/**
* @var array|null $proxy HTTP代理设置
*/
private $proxy = null;
/**
* HttpClient构造函数
*
* 初始化Guzzle HTTP客户端,设置默认配置
*
* @param array $config 自定义配置项,将覆盖默认配置
*/
public function __construct($config = [])
{
// 默认配置参数
$default_config = [
'connect_timeout' => 10 * 60, // 连接超时时间,10分钟
'timeout' => 10 * 60, // 请求超时时间,10分钟
'read_timeout' => 10 * 60, // 读取超时时间,10分钟
'verify' => false, // 不验证SSL证书
'http_errors' => false, // 不抛出HTTP错误异常
'allow_redirects' => false, // 默认不跟随重定向
];
// 初始化Guzzle客户端,合并默认配置和用户配置
$this->client = new Client(array_merge($default_config, $config));
}
/**
* 获取HttpClient的单例实例
*
* 如果实例不存在则创建新实例,否则返回已有实例
*
* @param array $config 配置项参数
* @return HttpClient 返回HttpClient实例
*/
public static function getInstance($config = [])
{
if (self::$instance === null) {
self::$instance = new self($config);
}
return self::$instance;
}
/**
* 设置全局HTTP请求头
*
* @param array $headers 请求头数组,格式为['Header-Name' => 'value']
* @return $this 返回当前实例,支持链式调用
*/
public function setHeaders($headers)
{
$this->headers = array_merge($this->headers, $headers);
return $this;
}
/**
* 设置请求的cookies
*
* 将cookies数组转换为cookie字符串并设置到请求头中
*
* @param array $cookies cookie数组,格式为['name' => 'value']
* @return $this 返回当前实例,支持链式调用
*/
public function setCookies(array $cookies)
{
// 构造cookie字符串,格式为"name1=value1; name2=value2"
$cookie_str = '';
foreach ($cookies as $key => $value) {
$cookie_str .= "{$key}={$value}; ";
}
$cookie_str = rtrim($cookie_str, '; ');
// 设置Cookie请求头
$this->headers['Cookie'] = $cookie_str;
return $this;
}
/**
* 设置HTTP代理
*
* 为HTTP和HTTPS请求设置代理服务器
*
* @param string $proxy 代理服务器地址,例如"http://127.0.0.1:8080"
* @return $this 返回当前实例,支持链式调用
*/
public function setProxy($proxy)
{
$this->proxy = [
'http' => $proxy,
'https' => $proxy,
];
return $this;
}
/**
* 发送GET请求
*
* @param string $url 请求URL
* @param array $data 查询参数数组
* @param array $options 额外的请求选项
* @return ResponseInterface 返回响应对象
*/
public function get($url, $data = [], $options = [])
{
$options['query'] = $data;
return $this->request('GET', $url, $options);
}
/**
* 发送POST表单请求
*
* @param string $url 请求URL
* @param array $data POST表单数据
* @param array $options 额外的请求选项
* @return ResponseInterface 返回响应对象
*/
public function post($url, $data = [], $options = [])
{
$options['form_params'] = $data;
return $this->request('POST', $url, $options);
}
/**
* 发送JSON格式的POST请求
*
* @param string $url 请求URL
* @param array $data 要发送的JSON数据
* @param array $options 额外的请求选项
* @return ResponseInterface 返回响应对象
*/
public function json($url, $data = [], $options = [])
{
$options['json'] = $data;
return $this->request('POST', $url, $options);
}
/**
* 核心请求方法
*
* 处理所有HTTP请求的通用逻辑
*
* @param string $method HTTP请求方法(GET, POST等)
* @param string $url 请求URL
* @param array $options 请求选项
* @return ResponseInterface 返回响应对象
*/
private function request($method, $url, $options = [])
{
// 合并全局请求头与本次请求头
$options['headers'] = array_merge(
$this->headers,
$options['headers'] ?? []
);
// 如果设置了代理,添加到请求选项中
if (!empty($this->proxy)) {
$options['proxy'] = $this->proxy;
}
return $this->client->request($method, $url, $options);
}
/**
* 发送异步GET请求
*
* @param string $url 请求URL
* @param array $options 请求选项
* @return PromiseInterface 返回Promise对象
*/
public function getAsync($url, $options = [])
{
return $this->requestAsync('GET', $url, $options);
}
/**
* 发送异步POST表单请求
*
* @param string $url 请求URL
* @param array $data POST表单数据
* @param array $options 请求选项
* @return PromiseInterface 返回Promise对象
*/
public function postAsync($url, $data = [], $options = [])
{
$options['form_params'] = $data;
return $this->requestAsync('POST', $url, $options);
}
/**
* 发送异步JSON格式的POST请求
*
* @param string $url 请求URL
* @param array $data 要发送的JSON数据
* @param array $options 请求选项
* @return PromiseInterface 返回Promise对象
*/
public function jsonAsync($url, $data = [], $options = [])
{
$options['json'] = $data;
return $this->requestAsync('POST', $url, $options);
}
/**
* 核心异步请求方法
*
* 处理所有异步HTTP请求的通用逻辑
*
* @param string $method HTTP请求方法(GET, POST等)
* @param string $url 请求URL
* @param array $options 请求选项
* @return PromiseInterface 返回Promise对象
*/
private function requestAsync($method, $url, $options = [])
{
// 合并全局请求头与本次请求头
$options['headers'] = array_merge(
$this->headers,
$options['headers'] ?? []
);
// 如果设置了代理,添加到请求选项中
if (!empty($this->proxy)) {
$options['proxy'] = $this->proxy;
}
return $this->client->requestAsync($method, $url, $options);
}
/**
* 等待并解析多个异步请求
*
* 等待所有Promise完成并返回结果
*
* @param array $promises 异步请求Promise数组
* @param bool $unwrap 是否展开结果(true返回响应内容,false返回Response对象)
* @return array 返回请求结果数组
*/
public function waitAll(array $promises, $unwrap = false)
{
$responses = Promise\Utils::unwrap($promises);
if (!$unwrap) {
return $responses;
}
$results = [];
foreach ($responses as $key => $response) {
$results[$key] = $response->getBody()->getContents();
}
return $results;
}
}
/**
* 使用示例:
*
* // 创建HttpClient实例
* $httpClient = HttpClient::getInstance();
*
* // 发起多个异步请求
* $promise1 = $httpClient->getAsync('https://api.example.com/data1');
* $promise2 = $httpClient->getAsync('https://api.example.com/data2');
* $promise3 = $httpClient->jsonAsync('https://api.example.com/submit', ['name' => 'test']);
*
* // 等待所有异步请求完成并获取结果
* $results = $httpClient->waitAll([
* 'data1' => $promise1,
* 'data2' => $promise2,
* 'submit' => $promise3
* ], true);
*/
推荐文章: