StreamWrapper.php 3.7 KB

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