HasHttpRequest.php 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. <?php
  2. namespace Yansongda\Supports\Traits;
  3. use GuzzleHttp\Client;
  4. use Psr\Http\Message\ResponseInterface;
  5. /**
  6. * Trait HasHttpRequest.
  7. *
  8. * @property string $baseUri
  9. * @property float $timeout
  10. * @property float $connectTimeout
  11. */
  12. trait HasHttpRequest
  13. {
  14. /**
  15. * Http client.
  16. *
  17. * @var Client|null
  18. */
  19. protected $httpClient = null;
  20. /**
  21. * Http client options.
  22. *
  23. * @var array
  24. */
  25. protected $httpOptions = [];
  26. /**
  27. * Send a GET request.
  28. *
  29. * @author yansongda <me@yansongda.cn>
  30. *
  31. * @return array|string
  32. */
  33. public function get(string $endpoint, array $query = [], array $headers = [])
  34. {
  35. return $this->request('get', $endpoint, [
  36. 'headers' => $headers,
  37. 'query' => $query,
  38. ]);
  39. }
  40. /**
  41. * Send a POST request.
  42. *
  43. * @author yansongda <me@yansongda.cn>
  44. *
  45. * @param string|array $data
  46. *
  47. * @return array|string
  48. */
  49. public function post(string $endpoint, $data, array $options = [])
  50. {
  51. if (!is_array($data)) {
  52. $options['body'] = $data;
  53. } else {
  54. $options['form_params'] = $data;
  55. }
  56. return $this->request('post', $endpoint, $options);
  57. }
  58. /**
  59. * Send request.
  60. *
  61. * @author yansongda <me@yansongda.cn>
  62. *
  63. * @return array|string
  64. */
  65. public function request(string $method, string $endpoint, array $options = [])
  66. {
  67. return $this->unwrapResponse($this->getHttpClient()->{$method}($endpoint, $options));
  68. }
  69. /**
  70. * Set http client.
  71. *
  72. * @author yansongda <me@yansongda.cn>
  73. *
  74. * @return $this
  75. */
  76. public function setHttpClient(Client $client): self
  77. {
  78. $this->httpClient = $client;
  79. return $this;
  80. }
  81. /**
  82. * Return http client.
  83. */
  84. public function getHttpClient(): Client
  85. {
  86. if (is_null($this->httpClient)) {
  87. $this->httpClient = $this->getDefaultHttpClient();
  88. }
  89. return $this->httpClient;
  90. }
  91. /**
  92. * Get default http client.
  93. *
  94. * @author yansongda <me@yansongda.cn>
  95. */
  96. public function getDefaultHttpClient(): Client
  97. {
  98. return new Client($this->getOptions());
  99. }
  100. /**
  101. * setBaseUri.
  102. *
  103. * @author yansongda <me@yansongda.cn>
  104. *
  105. * @return $this
  106. */
  107. public function setBaseUri(string $url): self
  108. {
  109. if (property_exists($this, 'baseUri')) {
  110. $parsedUrl = parse_url($url);
  111. $this->baseUri = ($parsedUrl['scheme'] ?? 'http').'://'.
  112. $parsedUrl['host'].(isset($parsedUrl['port']) ? (':'.$parsedUrl['port']) : '');
  113. }
  114. return $this;
  115. }
  116. /**
  117. * getBaseUri.
  118. *
  119. * @author yansongda <me@yansongda.cn>
  120. */
  121. public function getBaseUri(): string
  122. {
  123. return property_exists($this, 'baseUri') ? $this->baseUri : '';
  124. }
  125. public function getTimeout(): float
  126. {
  127. return property_exists($this, 'timeout') ? $this->timeout : 5.0;
  128. }
  129. public function setTimeout(float $timeout): self
  130. {
  131. if (property_exists($this, 'timeout')) {
  132. $this->timeout = $timeout;
  133. }
  134. return $this;
  135. }
  136. public function getConnectTimeout(): float
  137. {
  138. return property_exists($this, 'connectTimeout') ? $this->connectTimeout : 3.0;
  139. }
  140. public function setConnectTimeout(float $connectTimeout): self
  141. {
  142. if (property_exists($this, 'connectTimeout')) {
  143. $this->connectTimeout = $connectTimeout;
  144. }
  145. return $this;
  146. }
  147. /**
  148. * Get default options.
  149. *
  150. * @author yansongda <me@yansongda.cn>
  151. */
  152. public function getOptions(): array
  153. {
  154. return array_merge([
  155. 'base_uri' => $this->getBaseUri(),
  156. 'timeout' => $this->getTimeout(),
  157. 'connect_timeout' => $this->getConnectTimeout(),
  158. ], $this->getHttpOptions());
  159. }
  160. /**
  161. * setOptions.
  162. *
  163. * @author yansongda <me@yansongda.cn>
  164. *
  165. * @return $this
  166. */
  167. public function setOptions(array $options): self
  168. {
  169. return $this->setHttpOptions($options);
  170. }
  171. public function getHttpOptions(): array
  172. {
  173. return $this->httpOptions;
  174. }
  175. public function setHttpOptions(array $httpOptions): self
  176. {
  177. $this->httpOptions = $httpOptions;
  178. return $this;
  179. }
  180. /**
  181. * Convert response.
  182. *
  183. * @author yansongda <me@yansongda.cn>
  184. *
  185. * @return array|string
  186. */
  187. public function unwrapResponse(ResponseInterface $response)
  188. {
  189. $contentType = $response->getHeaderLine('Content-Type');
  190. $contents = $response->getBody()->getContents();
  191. if (false !== stripos($contentType, 'json') || stripos($contentType, 'javascript')) {
  192. return json_decode($contents, true);
  193. } elseif (false !== stripos($contentType, 'xml')) {
  194. return json_decode(json_encode(simplexml_load_string($contents, 'SimpleXMLElement', LIBXML_NOCDATA), JSON_UNESCAPED_UNICODE), true);
  195. }
  196. return $contents;
  197. }
  198. }