PHP断点续传封装类

 $filePath 文件路径
     * @param  $mimeType  文件类型
     * @param  $range 请求区域(范围)
     */
    function __construct($filePath, $mimeType = null , $range = null) {
        $this->filePath = $filePath;
        $this->fileSize = sprintf('%u',filesize($filePath));
        $this->mimeType = ($mimeType != null)?$mimeType:"application/octet-stream"; //  bin
        $this->range = trim($range);
    }
    /**
     *  获取文件区域
     * @return  {'start':long,'end':long} or null
     */
    private function getRange() {
        if (!empty($this->range)) {
            $range = preg_replace('/[\s|,].*/','',$this->range);
            $range = explode('-',substr($range,6));
            if (count($range) < 2 ) {
                $range[1] = $this->fileSize; // Range: bytes=-100
            }
            $range = array_combine(array('start','end'),$range);
            if (empty($range['start'])) {
                $range['start'] = 0;
            }
            if (!isset ($range['end']) || empty($range['end'])) {
                $range['end'] = $this->fileSize;
            }
            return $range;
        }
        return null;
    }
    /**
     * 向客户端发送文件
     */
    public function send() {
        $fileHande = fopen($this->filePath, 'rb');
        if ($fileHande) {
            // setting
            ob_end_clean();// clean cache
            ob_start();
            ini_set('output_buffering', 'Off');
            ini_set('zlib.output_compression', 'Off');
            $magicQuotes = get_magic_quotes_gpc();
       //     set_magic_quotes_runtime(0);
            // init
            $lastModified = gmdate('D, d M Y H:i:s', filemtime($this->filePath)).' GMT';
            $etag = sprintf('w/"%s:%s"',md5($lastModified),$this->fileSize);
            $ranges = $this->getRange();
            // headers
            header(sprintf('Last-Modified: %s',$lastModified));
            header(sprintf('ETag: %s',$etag));
            header(sprintf('Content-Type: %s',$this->mimeType));
            $disposition = 'attachment';
            if (strpos($this->mimeType,'image/') !== FALSE) {
                $disposition = 'inline';
            }
            header(sprintf('Content-Disposition: %s; filename="%s"',$disposition,basename($this->filePath)));

            if ($ranges != null) {
                if ($this->isLog) {
                    $this->log(json_encode($ranges).' '.$_SERVER['HTTP_RANGE']);
                }
                header('HTTP/1.1 206 Partial Content');
                header('Accept-Ranges: bytes');
                header(sprintf('Content-Length: %u',$ranges['end'] - $ranges['start']));
                header(sprintf('Content-Range: bytes %s-%s/%s', $ranges['start'], $ranges['end'],$this->fileSize));
                //
                fseek($fileHande, sprintf('%u',$ranges['start']));
            }else {
                header("HTTP/1.1 200 OK");
                header(sprintf('Content-Length: %s',$this->fileSize));
            }
            // read file
            $lastSize = 0;
            while(!feof($fileHande) && !connection_aborted()) {
                set_time_limit(0);
                $lastSize = sprintf("%u", bcsub($this->fileSize+1,sprintf("%u",ftell($fileHande))));
                if (bccomp($lastSize,self::BUFF_SIZE) > 0) {
                    $lastSize = self::BUFF_SIZE;
                }
                echo $lastSize;
                echo fread($fileHande, $lastSize);
                ob_flush();
                flush();
              //  sleep(1);
            }
         //   set_magic_quotes_runtime($magicQuotes);
            ob_end_flush();
        }
        if ($fileHande != null){
            fclose($fileHande);
        }
    }
    /**
     * 设置记录
     * @param  $isLog  是否记录
     */
    public function setIsLog($isLog = true) {
        $this->isLog = $isLog;
    }
    /**
     * 记录
     * @param  $msg  记录信息
     */
    private function log($msg) {
        try {
            $handle = fopen('transfer_log.txt', 'a');
            fwrite($handle, sprintf('%s : %s'.PHP_EOL,date('Y-m-d H:i:s'),$msg));
            fclose($handle);
        }catch(Exception $e) {
            // null;
        }
    }
}
date_default_timezone_set('Asia/Shanghai');
error_reporting(E_STRICT);
function errorHandler($errno, $errstr, $errfile, $errline) {
    echo '

error:',$errstr,'

'; exit(); } set_error_handler('errorHandler'); define('IS_DEBUG',true); // // $filePath = 'C:\Users\jack\Desktop\45.txt'; $type=pathinfo($filePath, PATHINFO_EXTENSION); $type=strtolower($type); if($type=="doc"||$type=="docx"){ $mimeType="application/msword"; }else if($type=="exe"){ $mimeType="application/x-msdownload"; }else if($type=="jpg"||$type=="jpeg"){ $mimeType="image/jpeg"; }else if($type=="pdf"){ $mimeType="application/pdf"; }else if($type=="xls"){ $mimeType="application/vnd.ms-excel"; }else { $mimeType = "application/octet-stream"; } $range = isset($_SERVER['HTTP_RANGE'])?$_SERVER['HTTP_RANGE']:null; if (IS_DEBUG) { // $range = "bytes=1000-1999\n2000"; // $range = "bytes=1000-1999,2000"; // $range = "bytes=1000-1999,-2000"; // $range = "bytes=1000-1999,2000-2999"; } set_time_limit(0); $transfer = new Transfer($filePath,$mimeType,$range); if (IS_DEBUG) { $transfer->setIsLog(true); } $transfer->send(); ?>

你可能感兴趣的:(php)