酒店预订平台
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.
 
 
 
 
 
 

166 lines
3.7 KiB

  1. <?php
  2. namespace GuzzleHttp\Psr7;
  3. use Psr\Http\Message\StreamInterface;
  4. /**
  5. * Converts Guzzle streams into PHP stream resources.
  6. *
  7. * @final
  8. */
  9. class StreamWrapper
  10. {
  11. /** @var resource */
  12. public $context;
  13. /** @var StreamInterface */
  14. private $stream;
  15. /** @var string r, r+, or w */
  16. private $mode;
  17. /**
  18. * Returns a resource representing the stream.
  19. *
  20. * @param StreamInterface $stream The stream to get a resource for
  21. *
  22. * @return resource
  23. *
  24. * @throws \InvalidArgumentException if stream is not readable or writable
  25. */
  26. public static function getResource(StreamInterface $stream)
  27. {
  28. self::register();
  29. if ($stream->isReadable()) {
  30. $mode = $stream->isWritable() ? 'r+' : 'r';
  31. } elseif ($stream->isWritable()) {
  32. $mode = 'w';
  33. } else {
  34. throw new \InvalidArgumentException('The stream must be readable, '
  35. . 'writable, or both.');
  36. }
  37. return fopen('guzzle://stream', $mode, null, self::createStreamContext($stream));
  38. }
  39. /**
  40. * Creates a stream context that can be used to open a stream as a php stream resource.
  41. *
  42. * @param StreamInterface $stream
  43. *
  44. * @return resource
  45. */
  46. public static function createStreamContext(StreamInterface $stream)
  47. {
  48. return stream_context_create([
  49. 'guzzle' => ['stream' => $stream]
  50. ]);
  51. }
  52. /**
  53. * Registers the stream wrapper if needed
  54. */
  55. public static function register()
  56. {
  57. if (!in_array('guzzle', stream_get_wrappers())) {
  58. stream_wrapper_register('guzzle', __CLASS__);
  59. }
  60. }
  61. public function stream_open($path, $mode, $options, &$opened_path)
  62. {
  63. $options = stream_context_get_options($this->context);
  64. if (!isset($options['guzzle']['stream'])) {
  65. return false;
  66. }
  67. $this->mode = $mode;
  68. $this->stream = $options['guzzle']['stream'];
  69. return true;
  70. }
  71. public function stream_read($count)
  72. {
  73. return $this->stream->read($count);
  74. }
  75. public function stream_write($data)
  76. {
  77. return (int) $this->stream->write($data);
  78. }
  79. public function stream_tell()
  80. {
  81. return $this->stream->tell();
  82. }
  83. public function stream_eof()
  84. {
  85. return $this->stream->eof();
  86. }
  87. public function stream_seek($offset, $whence)
  88. {
  89. $this->stream->seek($offset, $whence);
  90. return true;
  91. }
  92. public function stream_cast($cast_as)
  93. {
  94. $stream = clone($this->stream);
  95. return $stream->detach();
  96. }
  97. public function stream_stat()
  98. {
  99. static $modeMap = [
  100. 'r' => 33060,
  101. 'rb' => 33060,
  102. 'r+' => 33206,
  103. 'w' => 33188,
  104. 'wb' => 33188
  105. ];
  106. return [
  107. 'dev' => 0,
  108. 'ino' => 0,
  109. 'mode' => $modeMap[$this->mode],
  110. 'nlink' => 0,
  111. 'uid' => 0,
  112. 'gid' => 0,
  113. 'rdev' => 0,
  114. 'size' => $this->stream->getSize() ?: 0,
  115. 'atime' => 0,
  116. 'mtime' => 0,
  117. 'ctime' => 0,
  118. 'blksize' => 0,
  119. 'blocks' => 0
  120. ];
  121. }
  122. public function url_stat($path, $flags)
  123. {
  124. return [
  125. 'dev' => 0,
  126. 'ino' => 0,
  127. 'mode' => 0,
  128. 'nlink' => 0,
  129. 'uid' => 0,
  130. 'gid' => 0,
  131. 'rdev' => 0,
  132. 'size' => 0,
  133. 'atime' => 0,
  134. 'mtime' => 0,
  135. 'ctime' => 0,
  136. 'blksize' => 0,
  137. 'blocks' => 0
  138. ];
  139. }
  140. }