You are here

class Stream in Zircon Profile 8

Same name in this branch
  1. 8 vendor/zendframework/zend-diactoros/src/Stream.php \Zend\Diactoros\Stream
  2. 8 vendor/guzzlehttp/psr7/src/Stream.php \GuzzleHttp\Psr7\Stream
  3. 8 vendor/symfony/psr-http-message-bridge/Tests/Fixtures/Stream.php \Symfony\Bridge\PsrHttpMessage\Tests\Fixtures\Stream
Same name and namespace in other branches
  1. 8.0 vendor/guzzlehttp/psr7/src/Stream.php \GuzzleHttp\Psr7\Stream

PHP stream implementation.

Hierarchy

Expanded class hierarchy of Stream

2 files declare their use of Stream
LimitStreamTest.php in vendor/guzzlehttp/psr7/tests/LimitStreamTest.php
StreamTest.php in vendor/guzzlehttp/psr7/tests/StreamTest.php

File

vendor/guzzlehttp/psr7/src/Stream.php, line 11

Namespace

GuzzleHttp\Psr7
View source
class Stream implements StreamInterface {
  private $stream;
  private $size;
  private $seekable;
  private $readable;
  private $writable;
  private $uri;
  private $customMetadata;

  /** @var array Hash of readable and writable stream types */
  private static $readWriteHash = [
    'read' => [
      '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,
    ],
  ];

  /**
   * This constructor accepts an associative array of options.
   *
   * - size: (int) If a read stream would otherwise have an indeterminate
   *   size, but the size is known due to foreknownledge, then you can
   *   provide that size, in bytes.
   * - metadata: (array) Any additional metadata to return when the metadata
   *   of the stream is accessed.
   *
   * @param resource $stream  Stream resource to wrap.
   * @param array    $options Associative array of options.
   *
   * @throws \InvalidArgumentException if the stream is not a stream resource
   */
  public function __construct($stream, $options = []) {
    if (!is_resource($stream)) {
      throw new \InvalidArgumentException('Stream must be a resource');
    }
    if (isset($options['size'])) {
      $this->size = $options['size'];
    }
    $this->customMetadata = isset($options['metadata']) ? $options['metadata'] : [];
    $this->stream = $stream;
    $meta = stream_get_meta_data($this->stream);
    $this->seekable = $meta['seekable'];
    $this->readable = isset(self::$readWriteHash['read'][$meta['mode']]);
    $this->writable = isset(self::$readWriteHash['write'][$meta['mode']]);
    $this->uri = $this
      ->getMetadata('uri');
  }
  public function __get($name) {
    if ($name == 'stream') {
      throw new \RuntimeException('The stream is detached');
    }
    throw new \BadMethodCallException('No value for ' . $name);
  }

  /**
   * Closes the stream when the destructed
   */
  public function __destruct() {
    $this
      ->close();
  }
  public function __toString() {
    try {
      $this
        ->seek(0);
      return (string) stream_get_contents($this->stream);
    } catch (\Exception $e) {
      return '';
    }
  }
  public function getContents() {
    $contents = stream_get_contents($this->stream);
    if ($contents === false) {
      throw new \RuntimeException('Unable to read stream contents');
    }
    return $contents;
  }
  public function close() {
    if (isset($this->stream)) {
      if (is_resource($this->stream)) {
        fclose($this->stream);
      }
      $this
        ->detach();
    }
  }
  public function detach() {
    if (!isset($this->stream)) {
      return null;
    }
    $result = $this->stream;
    unset($this->stream);
    $this->size = $this->uri = null;
    $this->readable = $this->writable = $this->seekable = false;
    return $result;
  }
  public function getSize() {
    if ($this->size !== null) {
      return $this->size;
    }
    if (!isset($this->stream)) {
      return null;
    }

    // Clear the stat cache if the stream has a URI
    if ($this->uri) {
      clearstatcache(true, $this->uri);
    }
    $stats = fstat($this->stream);
    if (isset($stats['size'])) {
      $this->size = $stats['size'];
      return $this->size;
    }
    return null;
  }
  public function isReadable() {
    return $this->readable;
  }
  public function isWritable() {
    return $this->writable;
  }
  public function isSeekable() {
    return $this->seekable;
  }
  public function eof() {
    return !$this->stream || feof($this->stream);
  }
  public function tell() {
    $result = ftell($this->stream);
    if ($result === false) {
      throw new \RuntimeException('Unable to determine stream position');
    }
    return $result;
  }
  public function rewind() {
    $this
      ->seek(0);
  }
  public function seek($offset, $whence = SEEK_SET) {
    if (!$this->seekable) {
      throw new \RuntimeException('Stream is not seekable');
    }
    elseif (fseek($this->stream, $offset, $whence) === -1) {
      throw new \RuntimeException('Unable to seek to stream position ' . $offset . ' with whence ' . var_export($whence, true));
    }
  }
  public function read($length) {
    if (!$this->readable) {
      throw new \RuntimeException('Cannot read from non-readable stream');
    }
    return fread($this->stream, $length);
  }
  public function write($string) {
    if (!$this->writable) {
      throw new \RuntimeException('Cannot write to a non-writable stream');
    }

    // We can't know the size after writing anything
    $this->size = null;
    $result = fwrite($this->stream, $string);
    if ($result === false) {
      throw new \RuntimeException('Unable to write to stream');
    }
    return $result;
  }
  public function getMetadata($key = null) {
    if (!isset($this->stream)) {
      return $key ? null : [];
    }
    elseif (!$key) {
      return $this->customMetadata + stream_get_meta_data($this->stream);
    }
    elseif (isset($this->customMetadata[$key])) {
      return $this->customMetadata[$key];
    }
    $meta = stream_get_meta_data($this->stream);
    return isset($meta[$key]) ? $meta[$key] : null;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
Stream::$customMetadata private property
Stream::$readable private property
Stream::$readWriteHash private static property @var array Hash of readable and writable stream types
Stream::$seekable private property
Stream::$size private property
Stream::$stream private property
Stream::$uri private property
Stream::$writable private property
Stream::close public function Closes the stream and any underlying resources. Overrides StreamInterface::close
Stream::detach public function Separates any underlying resources from the stream. Overrides StreamInterface::detach
Stream::eof public function Returns true if the stream is at the end of the stream. Overrides StreamInterface::eof
Stream::getContents public function Returns the remaining contents in a string Overrides StreamInterface::getContents
Stream::getMetadata public function Get stream metadata as an associative array or retrieve a specific key. Overrides StreamInterface::getMetadata
Stream::getSize public function Get the size of the stream if known. Overrides StreamInterface::getSize
Stream::isReadable public function Returns whether or not the stream is readable. Overrides StreamInterface::isReadable
Stream::isSeekable public function Returns whether or not the stream is seekable. Overrides StreamInterface::isSeekable
Stream::isWritable public function Returns whether or not the stream is writable. Overrides StreamInterface::isWritable
Stream::read public function Read data from the stream. Overrides StreamInterface::read
Stream::rewind public function Seek to the beginning of the stream. Overrides StreamInterface::rewind
Stream::seek public function Seek to a position in the stream. Overrides StreamInterface::seek
Stream::tell public function Returns the current position of the file read/write pointer Overrides StreamInterface::tell
Stream::write public function Write data to the stream. Overrides StreamInterface::write
Stream::__construct public function This constructor accepts an associative array of options.
Stream::__destruct public function Closes the stream when the destructed
Stream::__get public function
Stream::__toString public function Reads all data from the stream into a string, from the beginning to end. Overrides StreamInterface::__toString