Response.php 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. <?php
  2. /**
  3. * 重庆赤晓店信息科技有限公司
  4. * https://www.chixiaodian.com
  5. * Copyright (c) 2023 赤店商城 All rights reserved.
  6. */
  7. /*
  8. * This file is part of the overtrue/wechat.
  9. *
  10. * (c) overtrue <i@overtrue.me>
  11. *
  12. * This source file is subject to the MIT license that is bundled
  13. * with this source code in the file LICENSE.
  14. */
  15. namespace ByteDance\Kernel\Http;
  16. use ByteDance\Kernel\Exceptions\InvalidArgumentException;
  17. use ByteDance\Kernel\Exceptions\RuntimeException;
  18. use ByteDance\Kernel\Support\File;
  19. use GuzzleHttp\Psr7\Response as GuzzleResponse;
  20. use ByteDance\Kernel\Support\Collection;
  21. use Psr\Http\Message\ResponseInterface;
  22. /**
  23. * Class Response.
  24. *
  25. * @author overtrue <i@overtrue.me>
  26. */
  27. class Response extends GuzzleResponse
  28. {
  29. /**
  30. * @return string
  31. */
  32. public function getBodyContents()
  33. {
  34. $this->getBody()->rewind();
  35. $contents = $this->getBody()->getContents();
  36. $this->getBody()->rewind();
  37. return $contents;
  38. }
  39. /**
  40. * @param \Psr\Http\Message\ResponseInterface $response
  41. *
  42. * @return \ByteDance\Kernel\Http\Response
  43. */
  44. public static function buildFromPsrResponse(ResponseInterface $response)
  45. {
  46. return new static(
  47. $response->getStatusCode(),
  48. $response->getHeaders(),
  49. $response->getBody(),
  50. $response->getProtocolVersion(),
  51. $response->getReasonPhrase()
  52. );
  53. }
  54. /**
  55. * Build to json.
  56. *
  57. * @return string
  58. */
  59. public function toJson()
  60. {
  61. return json_encode($this->toArray());
  62. }
  63. /**
  64. * Build to array.
  65. *
  66. * @return array
  67. */
  68. public function toArray()
  69. {
  70. $content = $this->removeControlCharacters($this->getBodyContents());
  71. $array = json_decode($content, true, 512, JSON_BIGINT_AS_STRING);
  72. if (JSON_ERROR_NONE === json_last_error()) {
  73. return (array) $array;
  74. }
  75. return [];
  76. }
  77. /**
  78. * Get collection data.
  79. *
  80. * @return \ByteDance\Kernel\Support\Collection
  81. */
  82. public function toCollection()
  83. {
  84. return new Collection($this->toArray());
  85. }
  86. /**
  87. * @return object
  88. */
  89. public function toObject()
  90. {
  91. return json_decode($this->toJson());
  92. }
  93. /**
  94. * @return bool|string
  95. */
  96. public function __toString()
  97. {
  98. return $this->getBodyContents();
  99. }
  100. /**
  101. * @param string $content
  102. *
  103. * @return string
  104. */
  105. protected function removeControlCharacters(string $content)
  106. {
  107. return \preg_replace('/[\x00-\x1F\x80-\x9F]/u', '', $content);
  108. }
  109. /**
  110. * @param string $directory
  111. * @param string $filename
  112. * @param bool $appendSuffix
  113. *
  114. * @return bool|int
  115. *
  116. * @throws \ByteDance\Kernel\Exceptions\InvalidArgumentException
  117. * @throws \ByteDance\Kernel\Exceptions\RuntimeException
  118. */
  119. public function save(string $directory, string $filename = '', bool $appendSuffix = true)
  120. {
  121. $this->getBody()->rewind();
  122. $directory = rtrim($directory, '/');
  123. if (!is_dir($directory)) {
  124. mkdir($directory, 0755, true); // @codeCoverageIgnore
  125. }
  126. if (!is_writable($directory)) {
  127. throw new InvalidArgumentException(sprintf("'%s' is not writable.", $directory));
  128. }
  129. $contents = $this->getBody()->getContents();
  130. if (empty($contents) || '{' === $contents[0]) {
  131. throw new RuntimeException('Invalid media response content.');
  132. }
  133. if (empty($filename)) {
  134. if (preg_match('/filename="(?<filename>.*?)"/', $this->getHeaderLine('Content-Disposition'), $match)) {
  135. $filename = $match['filename'];
  136. } else {
  137. $filename = md5($contents);
  138. }
  139. }
  140. if ($appendSuffix && empty(pathinfo($filename, PATHINFO_EXTENSION))) {
  141. $filename .= File::getStreamExt($contents);
  142. }
  143. file_put_contents($directory.'/'.$filename, $contents);
  144. return $filename;
  145. }
  146. }