php下载类型,支持下载本地文件和远程文件,支持回调函数

php实现下载文件的方式,直接通过设置header在浏览器下载资源,通过fopen方式是可以的,但是有时候遇到https类型的不一定成功(亲测某些不行),然后我的解决方案就是用curl获取下来后再用fopen读取方式下载。代码如下:

class Download
{
    //保存到本地
    public static function remote2local($url, $localPath)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        //开发环境取消ssl认证
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

        $res = curl_exec($ch);
        if (curl_errno($ch)) {
            echo "下载失败: " . PHP_EOL;
            print_r(curl_error($ch));
            exit('');
        }
        curl_close($ch);
        //保存到本地
        $file = fopen($localPath, 'w');
        fwrite($file, $res);
        fclose($file);
        return $localPath;
    }

    /**
     * 下载文件
     * @param $url string 文件地址,支持远程url
     * @param $filename string 下载的文件名
     * @param $callback callable 回调函数
     * @param  $tmPath string  远程文件临时保存路径
     * @param  $delRemoteTmp bool  是否删除远程文件下载本地的文件
     * @return void
     */
    public static function download_file($url, $filename = '', $callback = null, $tmPath = null, $delRemoteTmp = false)
    {
        $filename = $filename ?? md5(time() . rand(1, 999999));
        $path = parse_url($url, PHP_URL_PATH);
        $extension = pathinfo($path, PATHINFO_EXTENSION);
        $fileName = $filename . '.' . $extension;

        if (stripos($url, 'http') === 0) {
            //保存的临时路径
            $tmPath = $tmPath ?? RUNTIME_PATH . '/data/download/';
            if (!is_dir($tmPath)) mkdir($tmPath, 0777, true);
            $localPath = self::remote2local($url, $tmPath . $fileName);
            $isRemote = true;
        } else {
            $localPath = $url;
        }

        // 设置HTTP响应标头
        header('Content-Type: application/octet-stream');
        header('Content-Disposition: attachment; filename="' . $fileName . '"');
        $openFile = @fopen($localPath, 'rb');

        if ($openFile) {
            // 逐块输出文件内容到浏览器
            while (!feof($openFile)) {
                echo fread($openFile, 8192);
                ob_flush();
                flush();
            }
            $res = true;
            fclose($openFile);

            if (!empty($isRemote) && file_exists($localPath) && $delRemoteTmp) {
                unset($localPath);
            }
        } else {
            $res = false;
        }
        if (is_callable($callback)) {
            call_user_func($callback, $res);
        }
    }
}


支持远程文件和本地文件下载,调用实例:

Download::download_file($url,'文件abc',function ($res){
    if ($res){
        //统计下载量
    }
});


评论/留言