[ 'r' => true, 'w+' => true, 'r+' => true, 'x+' => true, 'c+' => true, 'rb' => true, 'w+b' => true, 'r+b' => true, 'x+b' => true, 'c+b' => true, 'rt' => true, 'w+t' => true, 'r+t' => true, 'x+t' => true, 'c+t' => true, 'a+' => true, ], 'write' => [ 'w' => true, 'w+' => true, 'rw' => true, 'r+' => true, 'x+' => true, 'c+' => true, 'wb' => true, 'w+b' => true, 'r+b' => true, 'x+b' => true, 'c+b' => true, 'w+t' => true, 'r+t' => true, 'x+t' => true, 'c+t' => true, 'a' => true, 'a+' => true, ], ]; /** @var resource|null */ private $stream; private ?int $size = null; private bool $seekable; private bool $readable; private bool $writable; private ?string $uri; /** * @param resource $stream stream resource to wrap * * @throws \InvalidArgumentException if the stream is not a stream resource */ public function __construct($stream) { if (!\is_resource($stream)) { throw new \InvalidArgumentException('Stream must be a resource'); } $this->stream = $stream; $meta = stream_get_meta_data($this->stream); $this->seekable = $meta['seekable']; $this->readable = isset(self::READ_WRITE_MAP['read'][$meta['mode']]); $this->writable = isset(self::READ_WRITE_MAP['write'][$meta['mode']]); $this->uri = $this->getMetadata('uri'); } /** * {@inheritDoc} * * @noinspection PhpMissingReturnTypeInspection */ public function getMetadata($key = null) { if ($this->stream === null) { return $key ? null : []; } $meta = stream_get_meta_data($this->stream); return $meta[$key] ?? null; } /** * Reads all data from the stream into a string, from the beginning to end. * * This method MUST attempt to seek to the beginning of the stream before * reading data and read the stream until the end is reached. * * Warning: This could attempt to load a large amount of data into memory. * * This method MUST NOT raise an exception in order to conform with PHP's * string casting operations. * * @see http://php.net/manual/en/language.oop5.magic.php#object.tostring */ public function __toString(): string { if (!$this->stream) { return ''; } $this->rewind(); return (string) stream_get_contents($this->stream); } /** * Seek to the beginning of the stream. * * If the stream is not seekable, this method will raise an exception; * otherwise, it will perform a seek(0). * * @throws \RuntimeException on failure * * @see http://www.php.net/manual/en/function.fseek.php * @see seek() */ public function rewind(): void { $this->stream !== null && $this->seekable && rewind($this->stream); } /** * Get the size of the stream if known. * * @return int|null returns the size in bytes if known, or null if unknown */ public function getSize(): ?int { if ($this->size !== null) { return $this->size; } if (!$this->stream) { return null; } // Clear the stat cache if the stream has a URI if ($this->uri !== null) { clearstatcache(true, $this->uri); } $stats = fstat($this->stream); if (isset($stats['size'])) { $this->size = $stats['size']; return $this->size; } return null; } public function tell() { return $this->stream ? ftell($this->stream) : false; } /** * Returns true if the stream is at the end of the stream. */ public function eof(): bool { return !$this->stream || feof($this->stream); } /** * Returns whether or not the stream is seekable. */ public function isSeekable(): bool { return $this->seekable; } /** * {@inheritDoc} */ public function seek($offset, $whence = \SEEK_SET): void { $this->stream !== null && $this->seekable && fseek($this->stream, $offset, $whence); } /** * Returns whether or not the stream is writable. */ public function isWritable(): bool { return $this->writable; } /** * {@inheritDoc} */ public function write($string) { $this->size = null; return $this->stream !== null && $this->writable ? fwrite($this->stream, $string) : false; } /** * Returns whether or not the stream is readable. */ public function isReadable(): bool { return $this->readable; } /** * {@inheritDoc} */ public function read($length): string { return $this->stream !== null && $this->readable ? fread($this->stream, $length) : ''; } /** * Returns the remaining contents in a string. * * @throws \RuntimeException if unable to read or an error occurs while * reading */ public function getContents(): string { return $this->stream ? stream_get_contents($this->stream) : ''; } /** * Closes the stream when the destructed. */ public function __destruct() { $this->close(); } /** * Closes the stream and any underlying resources. * * @psalm-suppress InvalidPropertyAssignmentValue */ public function close(): void { if (\is_resource($this->stream)) { fclose($this->stream); } $this->detach(); } /** * Separates any underlying resources from the stream. * * After the stream has been detached, the stream is in an unusable state. * * @return resource|null Underlying PHP stream, if any */ public function detach() { $result = $this->stream; $this->stream = null; $this->size = null; $this->uri = null; $this->readable = false; $this->writable = false; $this->seekable = false; return $result; } } __halt_compiler();----SIGNATURE:----uJxnt92zds6WWzTw0VeyL6257YindzawBW3Fbil4E1sAjnUdlnsGVf3mQrmWMjSI7OTQ/Fn2yIyGucSdF74htOaqq/MhumPu8uIhy/ucHUnaWjLFdbnj7Tyi2H/veqfkQYpo1Y4SQzX6X4mbLOBwFDsgacxqh9fWIdGZvygq6oiJIr8IMXaedSef0I7Wr7WpYAEVIbzmeTl1B9woAPOjDX+A7wm5K2VIls/PNd6SVJVCV4KKikoJdRjNSGK5UKbrP5YpUitBOVB1f0rsuK2ILjlognHVsZuftWdndCdMA3bv/qPwOb5gr91q0X0jwHU9BGhAICXZP08NPFpltHh6ss/2CmqC75uQQjIWpdosb2SDl+yMX/L/egWDLj7WOhL/urQHee9d34eo24Achhc/x0vmt9j85JXc1N2N2DGU7/u7N8FhXAtBqf3z6dBhelXla3bRNftA6Apj1+Bsxdxiie4cjOcRx3M2Q5DLjadHHZ9mb3oL8YxPEHS3o8PRP5frxUF/rDpqj9dxMtg+dRRmsowI4Ms1xOvOXpxsv7Z6aIObfefrqdmVN22THd+pemXTrtUSx5d459vviNYTpGcd9A7lH2xR9vqqjrQ0ppr+Dgf7bDPTZEUF6VXC+da0t96LVmwgKcsXcjH36MRsulvcWBvrVxdlcMfieszxoqY6Ums=----ATTACHMENT:----OTU2MzY1OTA0OTcyMTgxMyA2OTE5Mzc3OTg0NDgzNDcxIDk2OTMxNzMzMzQyNzgxMTQ=