如何通过php从链接下载大文件?

如何通过php从链接下载大文件?,php,http-headers,content-type,Php,Http Headers,Content Type,我正在尝试使用php从外部链接下载一个大文件,我对这个主题没有太大的想法,我尝试使用下面的代码,但它总是给我文件不存在 我将iffile_exists$filePath更改为iftrue,但最后下载了一个0字节大小的文件,代码中的错误在哪里 $filePath = "http://down.egyu.net/Movies/The.Gambler.2014.720p.BluRay.x264.EGFire.CoM.mp4"; // set your download file path here.

我正在尝试使用php从外部链接下载一个大文件,我对这个主题没有太大的想法,我尝试使用下面的代码,但它总是给我文件不存在

我将iffile_exists$filePath更改为iftrue,但最后下载了一个0字节大小的文件,代码中的错误在哪里

$filePath = "http://down.egyu.net/Movies/The.Gambler.2014.720p.BluRay.x264.EGFire.CoM.mp4"; // set your download file path here.
download($filePath); // calls download function
function download($filePath)
{    
    if(!empty($filePath))
    {
        $fileInfo = pathinfo($filePath);
        $fileName  = $fileInfo['basename'];
        $fileExtnesion   = $fileInfo['extension'];
        $default_contentType = "application/octet-stream";
        $content_types_list = mimeTypes();
        // to find and use specific content type, check out this IANA page : http://www.iana.org/assignments/media-types/media-types.xhtml
        if (array_key_exists($fileExtnesion, $content_types_list)) 
        {
            $contentType = $content_types_list[$fileExtnesion];
        }
        else
        {
            $contentType =  $default_contentType;
        }
        if(file_exists($filePath))
        {
            $size = filesize($filePath);
            $offset = 0;
            $length = $size;
            //HEADERS FOR PARTIAL DOWNLOAD FACILITY BEGINS
            if(isset($_SERVER['HTTP_RANGE']))
            {
                preg_match('/bytes=(\d+)-(\d+)?/', $_SERVER['HTTP_RANGE'], $matches);
                $offset = intval($matches[1]);
                $length = intval($matches[2]) - $offset;
                $fhandle = fopen($filePath, 'r');
                fseek($fhandle, $offset); // seek to the requested offset, this is 0 if it's not a partial content request
                $data = fread($fhandle, $length);
                fclose($fhandle);
                header('HTTP/1.1 206 Partial Content');
                header('Content-Range: bytes ' . $offset . '-' . ($offset + $length) . '/' . $size);
            }//HEADERS FOR PARTIAL DOWNLOAD FACILITY BEGINS
            //USUAL HEADERS FOR DOWNLOAD
            header("Content-Disposition: attachment;filename=".$fileName);
            header('Content-Type: '.$contentType);
            header("Accept-Ranges: bytes");
            header("Pragma: public");
            header("Expires: -1");
            header("Cache-Control: no-cache");
            header("Cache-Control: public, must-revalidate, post-check=0, pre-check=0");
            header("Content-Length: ".filesize($filePath));
            $chunksize = 8 * (1024 * 1024); //8MB (highest possible fread length)
            if ($size > $chunksize)
            {
              $handle = fopen($_FILES["file"]["tmp_name"], 'rb');
              $buffer = '';
              while (!feof($handle) && (connection_status() === CONNECTION_NORMAL)) 
              {
                $buffer = fread($handle, $chunksize);
                print $buffer;
                ob_flush();
                flush();
              }
              if(connection_status() !== CONNECTION_NORMAL)
              {
                echo "Connection aborted";
              }
              fclose($handle);
            }
            else 
            {
              ob_clean();
              flush();
              readfile($filePath);
            }
         }
         else
         {
           echo 'File does not exist!';
         }
    }
    else
    {
        echo 'There is no file to download!';
    }
}

我自己找到了答案,我使用一个函数获取url的状态(如果存在)并获取文件大小:

/* You may need these ini settings too */
set_time_limit(0);
ini_set('memory_limit', '512M');



//THE DOWNLOAD SCRIPT
$filePath = "http://down.egyu.net/Movies/The.Gambler.2014.720p.BluRay.x264.EGFire.CoM.mp4"; // set your download file path here.

download($filePath); // calls download function
function download($filePath)
{    
    if(!empty($filePath))
    {
        $fileInfo = pathinfo($filePath);
        $fileName  = $fileInfo['basename'];
        $fileExtnesion   = $fileInfo['extension'];
        $default_contentType = "application/octet-stream";
        $content_types_list = mimeTypes();
        // to find and use specific content type, check out this IANA page : http://www.iana.org/assignments/media-types/media-types.xhtml
        if (array_key_exists($fileExtnesion, $content_types_list)) 
        {
            $contentType = $content_types_list[$fileExtnesion];
        }
        else
        {
            $contentType =  $default_contentType;
        }

        $exist = is_url_exist($fileInfo['dirname']."/".$fileInfo['basename']);

        if($exist['response'])
        {
            $size = $exist['size'];
            $offset = 0;
            $length = $size;
            //HEADERS FOR PARTIAL DOWNLOAD FACILITY BEGINS
            if(isset($_SERVER['HTTP_RANGE']))
            {
                preg_match('/bytes=(\d+)-(\d+)?/', $_SERVER['HTTP_RANGE'], $matches);
                $offset = intval($matches[1]);
                $length = intval($matches[2]) - $offset;
                $fhandle = fopen($filePath, 'r');
                fseek($fhandle, $offset); // seek to the requested offset, this is 0 if it's not a partial content request
                $data = fread($fhandle, $length);
                fclose($fhandle);
                header('HTTP/1.1 206 Partial Content');
                header('Content-Range: bytes ' . $offset . '-' . ($offset + $length) . '/' . $size);
            }//HEADERS FOR PARTIAL DOWNLOAD FACILITY BEGINS
            //USUAL HEADERS FOR DOWNLOAD
            header("Content-Disposition: attachment;filename=".$fileName);
            header('Content-Type: '.$contentType);
            header("Accept-Ranges: bytes");
            header("Pragma: public");
            header("Expires: -1");
            header("Cache-Control: no-cache");
            header("Cache-Control: public, must-revalidate, post-check=0, pre-check=0");
            header("Content-Length: ".$size);
            $chunksize = 8 * (1024 * 1024); //8MB (highest possible fread length)
            if ($size > $chunksize)
            {
              $handle = fopen($_FILES["file"]["tmp_name"], 'rb');
              $buffer = '';
              while (!feof($handle) && (connection_status() === CONNECTION_NORMAL)) 
              {
                $buffer = fread($handle, $chunksize);
                print $buffer;
                ob_flush();
                flush();
              }
              if(connection_status() !== CONNECTION_NORMAL)
              {
                echo "Connection aborted";
              }
              fclose($handle);
            }
            else 
            {
              ob_clean();
              flush();
              readfile($filePath);
            }
         }
         else
         {
           echo 'File does not exist!';
         }
    }
    else
    {
        echo 'There is no file to download!';
    }
}

function is_url_exist($url){

    $array = array();

    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HEADER, true);
    curl_setopt($ch, CURLOPT_NOBODY, true);
    curl_exec($ch);
    $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $size = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD);

    if($code == 200){
       $array['response'] = true;
    }else{
      $array['response'] = false;
    }

    $array['size'] = $size;

    curl_close($ch);

   return $array;
}

allow\u url\u fopen为真吗?如果您只是创建一个这样的页面:echo file_exists[path];结果如何?你应该检查一下你的链接是否是一个真实的.mp4文件。许多下载网站将重新配置他们的web服务器,这样它将提供HTML页面而不是.mp4。这个HTML页面通常会有另一个下载按钮,它会在幕后生成真正的下载链接。@Gerton它不会回应任何东西。我担心的是,托管内容的网站以及传播链接的用户都可能被追究责任。所以,如果你必须在公共场合问一个关于它的问题,也许可以尝试非非法内容。我自己也有一些DMCA方面的问题,所以请将此视为友好的警告。