StreamWrapper.php 3.7 KB

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