TYPO3 CMS  TYPO3_8-7
Stream.php
Go to the documentation of this file.
1 <?php
2 namespace TYPO3\CMS\Core\Http;
3 
4 /*
5  * This file is part of the TYPO3 CMS project.
6  *
7  * It is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License, either version 2
9  * of the License, or any later version.
10  *
11  * For the full copyright and license information, please read the
12  * LICENSE.txt file that was distributed with this source code.
13  *
14  * The TYPO3 project - inspiring people to share!
15  */
16 
18 
27 class Stream implements StreamInterface
28 {
33  protected $resource;
34 
38  protected $stream;
39 
47  public function __construct($stream, $mode = 'r')
48  {
49  $this->stream = $stream;
50  if (is_resource($stream)) {
51  $this->resource = $stream;
52  } elseif (is_string($stream)) {
53  $this->resource = fopen($stream, $mode);
54  } else {
55  throw new \InvalidArgumentException('Invalid stream provided; must be a string stream identifier or resource', 1436717284);
56  }
57  }
58 
73  public function __toString()
74  {
75  if (!$this->isReadable()) {
76  return '';
77  }
78  try {
79  $this->rewind();
80  return $this->getContents();
81  } catch (\RuntimeException $e) {
82  return '';
83  }
84  }
85 
89  public function close()
90  {
91  if (!$this->resource) {
92  return;
93  }
94  $resource = $this->detach();
95  fclose($resource);
96  }
97 
105  public function detach()
106  {
108  $this->resource = null;
109  return $resource;
110  }
111 
117  public function getSize()
118  {
119  if ($this->resource === null) {
120  return null;
121  }
122  $stats = fstat($this->resource);
123  return $stats['size'];
124  }
125 
132  public function tell()
133  {
134  if (!$this->resource) {
135  throw new \RuntimeException('No resource available; cannot tell position', 1436717285);
136  }
137  $result = ftell($this->resource);
138  if (!is_int($result)) {
139  throw new \RuntimeException('Error occurred during tell operation', 1436717286);
140  }
141  return $result;
142  }
143 
149  public function eof()
150  {
151  if (!$this->resource) {
152  return true;
153  }
154  return feof($this->resource);
155  }
156 
162  public function isSeekable()
163  {
164  if (!$this->resource) {
165  return false;
166  }
167  return (bool)$this->getMetadata('seekable');
168  }
169 
184  public function seek($offset, $whence = SEEK_SET)
185  {
186  if (!$this->resource) {
187  throw new \RuntimeException('No resource available; cannot seek position', 1436717287);
188  }
189 
190  if (!$this->isSeekable()) {
191  throw new \RuntimeException('Stream is not seekable', 1436717288);
192  }
193  $result = fseek($this->resource, $offset, $whence);
194  if ($result !== 0) {
195  throw new \RuntimeException('Error seeking within stream', 1436717289);
196  }
197  }
198 
209  public function rewind()
210  {
211  $this->seek(0);
212  }
213 
219  public function isWritable()
220  {
221  if (!$this->resource) {
222  return false;
223  }
224  $uri = $this->getMetadata('uri');
225  return is_writable($uri);
226  }
227 
235  public function write($string)
236  {
237  if (!$this->resource) {
238  throw new \RuntimeException('No resource available; cannot write', 1436717290);
239  }
240  $result = fwrite($this->resource, $string);
241  if ($result === false) {
242  throw new \RuntimeException('Error writing to stream', 1436717291);
243  }
244  return $result;
245  }
246 
252  public function isReadable()
253  {
254  if (!$this->resource) {
255  return false;
256  }
257  $mode = $this->getMetadata('mode');
258  return strpos($mode, 'r') !== false || strpos($mode, '+') !== false;
259  }
260 
271  public function read($length)
272  {
273  if (!$this->resource) {
274  throw new \RuntimeException('No resource available; cannot read', 1436717292);
275  }
276  if (!$this->isReadable()) {
277  throw new \RuntimeException('Stream is not readable', 1436717293);
278  }
279  $result = fread($this->resource, $length);
280  if ($result === false) {
281  throw new \RuntimeException('Error reading stream', 1436717294);
282  }
283  return $result;
284  }
285 
293  public function getContents()
294  {
295  if (!$this->isReadable()) {
296  return '';
297  }
298  $result = stream_get_contents($this->resource);
299  if ($result === false) {
300  throw new \RuntimeException('Error reading from stream', 1436717295);
301  }
302  return $result;
303  }
304 
319  public function getMetadata($key = null)
320  {
321  $metadata = stream_get_meta_data($this->resource);
322  if ($key === null) {
323  return $metadata;
324  }
325  if (!isset($metadata[$key])) {
326  return null;
327  }
328  return $metadata[$key];
329  }
330 
339  public function attach($resource, $mode = 'r')
340  {
341  $error = null;
342  if (!is_resource($resource) && is_string($resource)) {
343  set_error_handler(function ($e) use (&$error) {
344  $error = $e;
345  }, E_WARNING);
346  $resource = fopen($resource, $mode);
347  restore_error_handler();
348  }
349  if ($error) {
350  throw new \InvalidArgumentException('Invalid stream reference provided', 1436717296);
351  }
352  if (!is_resource($resource)) {
353  throw new \InvalidArgumentException('Invalid stream provided; must be a string stream identifier or resource', 1436717297);
354  }
355  $this->resource = $resource;
356  }
357 }
__construct($stream, $mode='r')
Definition: Stream.php:47
seek($offset, $whence=SEEK_SET)
Definition: Stream.php:184
attach($resource, $mode='r')
Definition: Stream.php:339