【PHP】本地文件&远程文件下载

<?php

/**
 * @description  文件下载 支持本地和远程文件(浏览器直接下载)
 * @param        $fileUrl  本地文件绝对路径 OR 远程文件地址
 * @param string $fileName 下载保存的文件名
 */
function download_file($fileUrl, $fileName = ''){
    if(!$fileUrl){
        return false;
    }
    if ($fileName == '') {
        $pathInfo = pathinfo($fileUrl);
        $fileName = $pathInfo['basename'];
    }

    if (!headers_sent()) {
        //直接下载本地文件
        if (file_exists($fileUrl)) {
            $fileOpen = fopen($fileUrl, 'rb');
            $fileSize = filesize($fileUrl);
            header("Cache-Control: public");//缓存控制
            header("Content-Type: application/octet-stream");
            header("Accept-Ranges: bytes");
            header("Content-Length: " . $fileSize);
            header('Access-Control-Expose-Headers: Content-Disposition');
            header("Content-Disposition: attachment; filename=" . $fileName);
            $chunk_size = 4096; // 针对大文件,规定每次读取文件的字节数为4096字节,直接输出数据
            $sum_buffer = 0; //总的缓冲的字节数
            ob_start(); // 开启缓冲区
            //只要没到文件尾,就一直读取
            while (!feof($fileOpen) && $sum_buffer < $fileSize) {
                echo fread($fileOpen, $chunk_size);
                $sum_buffer += $chunk_size;
                ob_flush(); // 刷新PHP缓冲区到Web服务器
                flush(); // 刷新Web服务器缓冲区到浏览器
            }
            ob_end_clean(); // 关闭缓冲区
            fclose($fileOpen);
            exit;
        }else{
            //直接下载远程文件并输出到浏览器
            ob_start();
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $fileUrl);
            curl_setopt($ch, CURLOPT_REFERER, "");
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_HEADER, 0);
            $cexecute = curl_exec($ch);
            curl_close($ch);
            header('Content-Disposition: attachment; filename="'.$fileName.'"');
            header('Content-Length:'.strlen($cexecute));
            echo $cexecute;
            ob_flush();
            flush();
            ob_end_clean();
            exit;
        }
    }else{
        exit;
    }

}


/**
 * @description  下载远程文件到本地
 * @param        $fileUrl
 * @param string $savaDir
 * @return bool|string
 */
function save_file($fileUrl,$savaDir='uploads/temporary/'){
    if(!$fileUrl){
        return false;
    }
    $savaDir = $savaDir ? rtrim($savaDir,'/').'/' : '';
    $localTemporaryDir = FILE_UPLOAD.$savaDir;//此处注意改成自己项目配置的文件下载目录
    if(!is_dir($localTemporaryDir)){
        mkdir($localTemporaryDir,0777,true);
    }

    $baseName = pathinfo($fileUrl)['basename'];
    $fName = substr($baseName,0,strpos($baseName, '?'));//去除文件的签名相关参数
    $localFile = $localTemporaryDir . $fName;

    if(file_exists($localFile)){
        unlink($localFile);
    }
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $fileUrl);
    curl_setopt($ch, CURLOPT_HEADER, FALSE);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 900);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
    curl_setopt($ch, CURLOPT_BINARYTRANSFER, TRUE);
    $file = curl_exec($ch);
    curl_close($ch);
    if(!strpos($file, '<Error>')){
        file_put_contents($localFile, $file);
    }
    if (file_exists($localFile)) {
        return $localFile;
    }
    return false;
}


?>

 

posted @ 2020-11-20 10:23  bug毁灭者  阅读(384)  评论(0编辑  收藏  举报