3v4l.org

run code in 300+ PHP versions simultaneously
<?php class StreamResponse { /** * @var string|null */ private $path; /** * @var resource|null */ private $stream; /** * @var int */ private $buffer = 102400; /** * @var int */ private $start = -1; /** * @var int */ private $end = -1; /** * @var int */ private $size = 0; /** * @var array<string, array<int, string>> */ private $headers; /** * @var int */ private $status; public function __construct(string $filePath, array $headers = [], int $status = 200) { $this->path = $filePath; $this->headers = $headers; $this->status = $status; } /** * Start streaming video content. */ public function send(): void { $this->open(); $this->setHeader(); $this->stream(); fclose($this->stream); } /** * Open stream. * * * @throws RuntimeException */ private function open(): void { if (!($this->stream = fopen($this->path, 'rb'))) { throw new RuntimeException('Could not open stream for reading'); } } /** * Set proper header to serve the video content. */ private function setHeader(): void { ob_get_clean(); http_response_code($this->status); foreach ($this->headers as $header => $values) { $values = (array) $values; header($header . ': ' . implode(',', $values)); } header('Content-Type: ' . mime_content_type($this->path), false); header('Cache-Control: max-age=2592000, public', false); header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 2592000) . ' GMT', false); header('Last-Modified: ' . gmdate('D, d M Y H:i:s', @filemtime($this->path)) . ' GMT', false); $this->start = 0; $this->size = filesize($this->path); $this->end = $this->size - 1; header('Accept-Ranges: 0-' . $this->end); if (isset($_SERVER['HTTP_RANGE'])) { $c_end = $this->end; [, $range] = explode('=', $_SERVER['HTTP_RANGE'], 2); if (false !== strpos($range, ',')) { header('HTTP/1.1 416 Requested Range Not Satisfiable'); header("Content-Range: bytes $this->start-$this->end/$this->size"); return; } if ('-' === $range) { $c_start = $this->size - substr($range, 1); } else { $range = explode('-', $range); $c_start = $range[0]; $c_end = (isset($range[1]) && is_numeric($range[1])) ? $range[1] : $c_end; } $c_end = ($c_end > $this->end) ? $this->end : $c_end; if ($c_start > $c_end || $c_start > $this->size - 1 || $c_end >= $this->size) { header('HTTP/1.1 416 Requested Range Not Satisfiable'); header('Content-Range: bytes ' . $this->start - $this->end . '/' . $this->size); return; } $this->start = $c_start; $this->end = $c_end; $length = $this->end - $this->start + 1; fseek($this->stream, $this->start); header('HTTP/1.1 206 Partial Content'); header('Content-Length: ' . $length); header('Content-Range: bytes ' . $this->start - $this->end . '/' . $this->size); } else { header('Content-Length: ' . $this->size); } } /** * perform the streaming of calculated range. */ private function stream(): void { $i = $this->start; set_time_limit(0); while (!feof($this->stream) && $i <= $this->end) { $bytesToRead = $this->buffer; if (($i + $bytesToRead) > $this->end) { $bytesToRead = $this->end - $i + 1; } $data = fread($this->stream, $bytesToRead); echo $data; flush(); $i += $bytesToRead; } } }
Output for 7.1.0 - 7.1.33, 7.2.0 - 7.2.34, 7.3.0 - 7.3.31, 7.4.0 - 7.4.25, 8.0.0 - 8.0.12
Output for 7.0.0 - 7.0.33
Parse error: syntax error, unexpected ',', expecting ']' in /in/KeUdg on line 99
Process exited with code 255.
Output for 5.6.0 - 5.6.40
Fatal error: Default value for parameters with a class type hint can only be NULL in /in/KeUdg on line 44
Process exited with code 255.

preferences:
148.75 ms | 401 KiB | 218 Q