香洲二院小程序
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
mini_xzey/app/Utils/Traits/HttpRequest.php

265 lines
6.0 KiB

<?php
declare(strict_types=1);
namespace App\Utils\Traits;
use GuzzleHttp\Client;
use GuzzleHttp\Handler\MockHandler;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Psr7\Response;
use InvalidArgumentException;
use JsonException;
use Psr\Http\Message\ResponseInterface;
trait HttpRequest
{
/**
* Http client.
*
* @var Client|null
*/
protected ?Client $httpClient = null;
/**
* Mock handler.
*
* @var MockHandler|null
*/
protected ?MockHandler $mockHandler = null;
/**
* Http header
*
* @var array<string, string>
*/
private array $httpHeader = [];
/**
* Http client options.
*
* @var array<string, mixed>
*/
protected array $httpOptions = [
'base_uri' => '',
'timeout' => 0,
'connect_timeout' => 0,
];
/**
* Send a GET request.
*
* @param string $endpoint 请求路由
* @param array<string, mixed> $query GET参数
* @param array<string, mixed> $headers 请求header头
*
* @return mixed
*
* @throws JsonException
*/
public function get(string $endpoint, array $query = [], array $headers = []): mixed
{
return $this->request('GET', $endpoint, [
'headers' => $headers,
'query' => $query,
]);
}
/**
* Send a POST request.
*
* @param string $endpoint 请求路由
* @param string|array<string, mixed> $data 请求数据
* @param array<string, mixed> $options options选项
*
* @return mixed
* @throws JsonException
*/
public function post(string $endpoint, string|array $data, array $options = []): mixed
{
if (!is_array($data)) {
$options['body'] = $data;
} else {
$options['form_params'] = $data;
}
return $this->request('POST', $endpoint, $options);
}
/**
* Send request.
*
* @param string $method 请求方法
* @param string $endpoint 请求路由
* @param array<string, mixed> $options options选项
*
* @return mixed
*
* @throws JsonException
*/
public function request(string $method, string $endpoint, array $options = []): mixed
{
return $this->unwrapResponse($this->getHttpClient()->{$method}($endpoint, $options));
}
/**
* Convert response.
*
* @param ResponseInterface $response 返回的response对象
*
* @return mixed
*
* @throws JsonException
*/
public function unwrapResponse(ResponseInterface $response): mixed
{
$contentType = $response->getHeaderLine('Content-Type');
$contents = $response->getBody()->getContents();
if (false !== stripos($contentType, 'json') || stripos($contentType, 'javascript')) {
return json_decode($contents, true, 512, JSON_THROW_ON_ERROR);
}
if (false !== stripos($contentType, 'xml')) {
return json_decode(
json_encode(
simplexml_load_string($contents, 'SimpleXMLElement', LIBXML_NOCDATA),
JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE
),
true,
512,
JSON_THROW_ON_ERROR
);
}
return $contents;
}
/**
* Set http client.
*
* @param Client $client client请求客户端
*
* @return self
*/
public function setHttpClient(Client $client): self
{
$this->httpClient = $client;
return $this;
}
/**
* Get http client.
*
* @return Client
*/
public function getHttpClient(): Client
{
if (is_null($this->httpClient)) {
$this->httpClient = $this->getDefaultHttpClient();
}
return $this->httpClient;
}
/**
* Get default http client.
*
* @return Client
*/
public function getDefaultHttpClient(): Client
{
return new Client($this->getOptions());
}
/**
* set mock Handler
*
* @param array<int, Response> $mock
*
* @return self
*/
public function setMockHandler(array $mock): self
{
array_walk($mock, static function ($value) {
if (!is_subclass_of($value, ResponseInterface::class)) {
throw new InvalidArgumentException(
$value::class . ' must be an instance of ' . ResponseInterface::class
);
}
});
$this->mockHandler = new MockHandler($mock);
$handlerStack = HandlerStack::create($this->mockHandler);
$this->setHttpOptions(['handler' => $handlerStack]);
return $this;
}
/**
* Get mock handler
*
* @return MockHandler|null
*/
public function getMockHandler(): ?MockHandler
{
return $this->mockHandler;
}
/**
* Get default options.
*
* @return array<string, mixed>
*/
public function getOptions(): array
{
return $this->getHttpOptions();
}
/**
* Set http header.
*
* @param array<string, string> $httpHeader
*
* @return self
*/
public function setHttpHeader(array $httpHeader): self
{
$this->httpHeader = array_merge($httpHeader, $this->httpHeader);
return $this;
}
/**
* Get http header.
*
* @return array<string, string>
*/
public function getHttpHeader(): array
{
return $this->httpHeader;
}
/**
* Set http options.
*
* @param array<string, HandlerStack|string> $httpOptions
*
* @return void
*/
public function setHttpOptions(array $httpOptions): void
{
$this->httpOptions = array_merge($this->httpOptions, $httpOptions);
}
/**
* Get http options.
*
* @return array<string, mixed>
*/
public function getHttpOptions(): array
{
return $this->httpOptions;
}
}