[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
1 <?php 2 3 declare(strict_types=1); 4 5 namespace Nyholm\Psr7; 6 7 use Psr\Http\Message\StreamInterface; 8 use Symfony\Component\Debug\ErrorHandler as SymfonyLegacyErrorHandler; 9 use Symfony\Component\ErrorHandler\ErrorHandler as SymfonyErrorHandler; 10 11 /** 12 * @author Michael Dowling and contributors to guzzlehttp/psr7 13 * @author Tobias Nyholm <[email protected]> 14 * @author Martijn van der Ven <[email protected]> 15 * 16 * @final This class should never be extended. See https://github.com/Nyholm/psr7/blob/master/doc/final.md 17 */ 18 class Stream implements StreamInterface 19 { 20 /** @var resource|null A resource reference */ 21 private $stream; 22 23 /** @var bool */ 24 private $seekable; 25 26 /** @var bool */ 27 private $readable; 28 29 /** @var bool */ 30 private $writable; 31 32 /** @var array|mixed|void|bool|null */ 33 private $uri; 34 35 /** @var int|null */ 36 private $size; 37 38 /** @var array Hash of readable and writable stream types */ 39 private const READ_WRITE_HASH = [ 40 'read' => [ 41 'r' => true, 'w+' => true, 'r+' => true, 'x+' => true, 'c+' => true, 42 'rb' => true, 'w+b' => true, 'r+b' => true, 'x+b' => true, 43 'c+b' => true, 'rt' => true, 'w+t' => true, 'r+t' => true, 44 'x+t' => true, 'c+t' => true, 'a+' => true, 45 ], 46 'write' => [ 47 'w' => true, 'w+' => true, 'rw' => true, 'r+' => true, 'x+' => true, 48 'c+' => true, 'wb' => true, 'w+b' => true, 'r+b' => true, 49 'x+b' => true, 'c+b' => true, 'w+t' => true, 'r+t' => true, 50 'x+t' => true, 'c+t' => true, 'a' => true, 'a+' => true, 51 ], 52 ]; 53 54 private function __construct() 55 { 56 } 57 58 /** 59 * Creates a new PSR-7 stream. 60 * 61 * @param string|resource|StreamInterface $body 62 * 63 * @throws \InvalidArgumentException 64 */ 65 public static function create($body = ''): StreamInterface 66 { 67 if ($body instanceof StreamInterface) { 68 return $body; 69 } 70 71 if (\is_string($body)) { 72 $resource = \fopen('php://temp', 'rw+'); 73 \fwrite($resource, $body); 74 $body = $resource; 75 } 76 77 if (\is_resource($body)) { 78 $new = new self(); 79 $new->stream = $body; 80 $meta = \stream_get_meta_data($new->stream); 81 $new->seekable = $meta['seekable'] && 0 === \fseek($new->stream, 0, \SEEK_CUR); 82 $new->readable = isset(self::READ_WRITE_HASH['read'][$meta['mode']]); 83 $new->writable = isset(self::READ_WRITE_HASH['write'][$meta['mode']]); 84 85 return $new; 86 } 87 88 throw new \InvalidArgumentException('First argument to Stream::create() must be a string, resource or StreamInterface.'); 89 } 90 91 /** 92 * Closes the stream when the destructed. 93 */ 94 public function __destruct() 95 { 96 $this->close(); 97 } 98 99 /** 100 * @return string 101 */ 102 public function __toString() 103 { 104 try { 105 if ($this->isSeekable()) { 106 $this->seek(0); 107 } 108 109 return $this->getContents(); 110 } catch (\Throwable $e) { 111 if (\PHP_VERSION_ID >= 70400) { 112 throw $e; 113 } 114 115 if (\is_array($errorHandler = \set_error_handler('var_dump'))) { 116 $errorHandler = $errorHandler[0] ?? null; 117 } 118 \restore_error_handler(); 119 120 if ($e instanceof \Error || $errorHandler instanceof SymfonyErrorHandler || $errorHandler instanceof SymfonyLegacyErrorHandler) { 121 return \trigger_error((string) $e, \E_USER_ERROR); 122 } 123 124 return ''; 125 } 126 } 127 128 public function close(): void 129 { 130 if (isset($this->stream)) { 131 if (\is_resource($this->stream)) { 132 \fclose($this->stream); 133 } 134 $this->detach(); 135 } 136 } 137 138 public function detach() 139 { 140 if (!isset($this->stream)) { 141 return null; 142 } 143 144 $result = $this->stream; 145 unset($this->stream); 146 $this->size = $this->uri = null; 147 $this->readable = $this->writable = $this->seekable = false; 148 149 return $result; 150 } 151 152 private function getUri() 153 { 154 if (false !== $this->uri) { 155 $this->uri = $this->getMetadata('uri') ?? false; 156 } 157 158 return $this->uri; 159 } 160 161 public function getSize(): ?int 162 { 163 if (null !== $this->size) { 164 return $this->size; 165 } 166 167 if (!isset($this->stream)) { 168 return null; 169 } 170 171 // Clear the stat cache if the stream has a URI 172 if ($uri = $this->getUri()) { 173 \clearstatcache(true, $uri); 174 } 175 176 $stats = \fstat($this->stream); 177 if (isset($stats['size'])) { 178 $this->size = $stats['size']; 179 180 return $this->size; 181 } 182 183 return null; 184 } 185 186 public function tell(): int 187 { 188 if (!isset($this->stream)) { 189 throw new \RuntimeException('Stream is detached'); 190 } 191 192 if (false === $result = @\ftell($this->stream)) { 193 throw new \RuntimeException('Unable to determine stream position: ' . (\error_get_last()['message'] ?? '')); 194 } 195 196 return $result; 197 } 198 199 public function eof(): bool 200 { 201 return !isset($this->stream) || \feof($this->stream); 202 } 203 204 public function isSeekable(): bool 205 { 206 return $this->seekable; 207 } 208 209 public function seek($offset, $whence = \SEEK_SET): void 210 { 211 if (!isset($this->stream)) { 212 throw new \RuntimeException('Stream is detached'); 213 } 214 215 if (!$this->seekable) { 216 throw new \RuntimeException('Stream is not seekable'); 217 } 218 219 if (-1 === \fseek($this->stream, $offset, $whence)) { 220 throw new \RuntimeException('Unable to seek to stream position "' . $offset . '" with whence ' . \var_export($whence, true)); 221 } 222 } 223 224 public function rewind(): void 225 { 226 $this->seek(0); 227 } 228 229 public function isWritable(): bool 230 { 231 return $this->writable; 232 } 233 234 public function write($string): int 235 { 236 if (!isset($this->stream)) { 237 throw new \RuntimeException('Stream is detached'); 238 } 239 240 if (!$this->writable) { 241 throw new \RuntimeException('Cannot write to a non-writable stream'); 242 } 243 244 // We can't know the size after writing anything 245 $this->size = null; 246 247 if (false === $result = @\fwrite($this->stream, $string)) { 248 throw new \RuntimeException('Unable to write to stream: ' . (\error_get_last()['message'] ?? '')); 249 } 250 251 return $result; 252 } 253 254 public function isReadable(): bool 255 { 256 return $this->readable; 257 } 258 259 public function read($length): string 260 { 261 if (!isset($this->stream)) { 262 throw new \RuntimeException('Stream is detached'); 263 } 264 265 if (!$this->readable) { 266 throw new \RuntimeException('Cannot read from non-readable stream'); 267 } 268 269 if (false === $result = @\fread($this->stream, $length)) { 270 throw new \RuntimeException('Unable to read from stream: ' . (\error_get_last()['message'] ?? '')); 271 } 272 273 return $result; 274 } 275 276 public function getContents(): string 277 { 278 if (!isset($this->stream)) { 279 throw new \RuntimeException('Stream is detached'); 280 } 281 282 if (false === $contents = @\stream_get_contents($this->stream)) { 283 throw new \RuntimeException('Unable to read stream contents: ' . (\error_get_last()['message'] ?? '')); 284 } 285 286 return $contents; 287 } 288 289 /** 290 * @return mixed 291 */ 292 public function getMetadata($key = null) 293 { 294 if (!isset($this->stream)) { 295 return $key ? null : []; 296 } 297 298 $meta = \stream_get_meta_data($this->stream); 299 300 if (null === $key) { 301 return $meta; 302 } 303 304 return $meta[$key] ?? null; 305 } 306 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Sep 7 05:41:13 2022 | Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer |