stream)) { throw new CommandException('Cannot read from closed stream'); } return fread($this->stream, $length) ?: null; } public function getContents(?int $length = null, int $offset = -1): ?string { if (!is_resource($this->stream)) { throw new CommandException('Cannot read from closed stream'); } $contents = stream_get_contents($this->stream, $length, $offset); return $contents === false ? null : $contents; } public function close(): bool { return is_resource($this->stream) ? fclose($this->stream) : true; } public function __destruct() { $this->close(); } }