Created
May 29, 2016 12:19
-
-
Save itskenny0/5a2588a43aa8a5452dde83ea3cbc9ae5 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* FileServe | |
* | |
* Class that serves a file from disk to a client. | |
* | |
* @package FileServe | |
* @author Kenny <[email protected]> | |
* @license The Unlicense (http://unlicense.org) | |
*/ | |
class FileServe { | |
private $stream; | |
private $filename; | |
const FILE_BUFFER = 8192; //buffer 8192 KByte of the file on every read. You might want to play with this value. | |
const CONTENT_TYPE = "application/octet-stream"; | |
/** | |
** Constructor | |
* | |
* Called when instantiating the class. | |
* | |
* @param str $filename Filename of the file to be read. | |
* @throws Exception if input file doesn't exist or cannot be read | |
*/ | |
public function __construct($filename) { | |
if(!file_exists($filename)) throw new Exception("The given input file does not exist."); | |
$this->stream = fopen($filename, 'r'); | |
$this->filename = basename($filename); | |
if($this->stream === false) throw new Exception("Could not read file. Please check permissions."); | |
else return true; | |
} | |
/** | |
* Serve file | |
* | |
* Starts serving the file to the client. | |
* | |
* @throws Exception if stream dead or file empty | |
* @param $throttle (optional) Defines amount of throttle in the transmission in nanoseconds. Defaults to no throttle. | |
* @return true after transmission completed | |
*/ | |
public function serve($throttle = 0) { | |
if(!is_resource($this->stream)) throw new Exception("The stream has gone away. This should not occur."); | |
if(feof($this->stream)) throw new Exception("The file is empty."); | |
header('Content-Type: ' . self::CONTENT_TYPE); | |
header('Content-Transfer-Encoding: Binary'); | |
header('Content-disposition: attachment: filename="' . $this->filename . '"'); | |
do { | |
echo $fileChunk; | |
if($throttle > 0) usleep($throttle); | |
} while (false !== ($fileChunk = $this->readChunk())); | |
return true; | |
} | |
/** | |
* Get next chunk | |
* | |
* Gets a chunk from the file and returns it. | |
* | |
* @return str chunk if chunk read correctly, false if file pointer is EOF | |
*/ | |
private function readChunk() { | |
if(feof($this->stream)) return false; | |
$chunk = fread($this->stream, self::FILE_BUFFER); | |
return $chunk; | |
} | |
} | |
/* Example usage */ | |
$fSrv = new FileServe("debian-8.4.0-amd64-netinst.iso"); | |
$fSrv->serve(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment