/** * Serve a file. * * Includes support for range requests/partial content. * * @param $file The absolute filename * @param $mime The mimetype of the file. * @param $filename The filename to serve the file as. */ public static function serve_file($file, $mime = '', $filename = '', $forcedownload = false) { if (!file_exists($file)) { throw new Exception('File not found', Exception::ERR_RESOURCE_NOT_FOUND); } if (empty($mime)) { $mime = \pdyn\filesystem\FilesystemUtils::get_mime_type($file); } if (empty($filename)) { $filename = basename($file); } static::caching_headers($file, filemtime($file), true); clearstatcache(); $fp = fopen($file, 'r'); $size = filesize($file); $length = $size; $start = 0; $end = $size - 1; header('Accept-Ranges: 0-' . $length); if (isset($_SERVER['HTTP_RANGE'])) { $c_start = $start; $c_end = $end; list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2); if (strpos($range, ',') !== false) { header('HTTP/1.1 416 Requested Range Not Satisfiable'); header('Content-Range: bytes ' . $start . '-' . $end . '/' . $size); exit; } if ($range == '-') { $c_start = $size - mb_substr($range, 1); } else { $range = explode('-', $range); $c_start = $range[0]; $c_end = isset($range[1]) && is_numeric($range[1]) ? $range[1] : $size; } $c_end = $c_end > $end ? $end : $c_end; if ($c_start > $c_end || $c_start > $size - 1 || $c_end >= $size) { header('HTTP/1.1 416 Requested Range Not Satisfiable'); header('Content-Range: bytes ' . $start . '-' . $end . '/' . $size); exit; } $start = $c_start; $end = $c_end; $length = $end - $start + 1; fseek($fp, $start); header('HTTP/1.1 206 Partial Content'); } header('Content-Range: bytes ' . $start . '-' . $end . '/' . $size); header('Content-Length: ' . $length); header('Content-Type: ' . $mime); if ($forcedownload === true) { header('Content-disposition: attachment; filename="' . $filename . '"'); } $buffer = 1024 * 8; while (!feof($fp) && ($p = ftell($fp)) <= $end) { if ($p + $buffer > $end) { $buffer = $end - $p + 1; } set_time_limit(0); echo fread($fp, $buffer); flush(); } fclose($fp); }
/** * Analyze the file for MIME type. * * @return string The mime type. */ public function get_analyzed_mimetype() { return \pdyn\filesystem\FilesystemUtils::get_mime_type($this->stored_filename); }
/** * Load an image file into the object. * * @param string $filename The filename of the image. * @param bool $loadexif Whether to load exif information (can cause memory problems with large files). */ protected function load_from_file($filename, $loadexif = true) { if (!file_exists($filename)) { throw new \Exception('File "' . $filename . '" not found', static::ERR_FILE_NOT_FOUND); } $this->filename = $filename; // Create image resource. $this->mime = \pdyn\filesystem\FilesystemUtils::get_mime_type($this->filename); switch ($this->mime) { case 'image/jpeg': $this->res = @imagecreatefromjpeg($this->filename); break; case 'image/png': $this->res = @imagecreatefrompng($this->filename); break; case 'image/gif': $this->res = @imagecreatefromgif($this->filename); break; default: throw new \Exception('Filetype not supported', static::ERR_FILETYPE_NOT_SUPPORTED); } if (empty($this->res)) { throw new \Exception('Error opening file.', static::ERR_BAD_INPUT); } if ($loadexif === true && $this->mime === 'image/jpeg') { $this->exif = $this->get_exif_pel(); } }