• <tfoot id='D273Y'></tfoot><legend id='D273Y'><style id='D273Y'><dir id='D273Y'><q id='D273Y'></q></dir></style></legend>
        <bdo id='D273Y'></bdo><ul id='D273Y'></ul>
      <i id='D273Y'><tr id='D273Y'><dt id='D273Y'><q id='D273Y'><span id='D273Y'><b id='D273Y'><form id='D273Y'><ins id='D273Y'></ins><ul id='D273Y'></ul><sub id='D273Y'></sub></form><legend id='D273Y'></legend><bdo id='D273Y'><pre id='D273Y'><center id='D273Y'></center></pre></bdo></b><th id='D273Y'></th></span></q></dt></tr></i><div id='D273Y'><tfoot id='D273Y'></tfoot><dl id='D273Y'><fieldset id='D273Y'></fieldset></dl></div>
    1. <small id='D273Y'></small><noframes id='D273Y'>

        PHP中是否有很好的实现部分文件下载?

        时间:2023-08-20
        • <bdo id='RTZVp'></bdo><ul id='RTZVp'></ul>
        • <tfoot id='RTZVp'></tfoot>

        • <legend id='RTZVp'><style id='RTZVp'><dir id='RTZVp'><q id='RTZVp'></q></dir></style></legend>
          • <i id='RTZVp'><tr id='RTZVp'><dt id='RTZVp'><q id='RTZVp'><span id='RTZVp'><b id='RTZVp'><form id='RTZVp'><ins id='RTZVp'></ins><ul id='RTZVp'></ul><sub id='RTZVp'></sub></form><legend id='RTZVp'></legend><bdo id='RTZVp'><pre id='RTZVp'><center id='RTZVp'></center></pre></bdo></b><th id='RTZVp'></th></span></q></dt></tr></i><div id='RTZVp'><tfoot id='RTZVp'></tfoot><dl id='RTZVp'><fieldset id='RTZVp'></fieldset></dl></div>
                <tbody id='RTZVp'></tbody>

                <small id='RTZVp'></small><noframes id='RTZVp'>

                  本文介绍了PHP中是否有很好的实现部分文件下载?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  我正在编写允许用户下载文件的 PHP 脚本.基本上这个想法是为了防止文件被下载超过 X 次,因为它是付费内容,链接不应该被传播.

                  I'm writing a PHP script that allows the user to download a file. Basically the idea is to prevent the file being downloaded more than X times, since it is paid content, and the link should not be spread around.

                  由于文件会很大,所以最好实现恢复.我已经阅读了标准,但它是很长,并允许一些灵活性.由于我需要快速完成它,我更喜欢此功能的稳定、经过测试的实现.

                  Since the files will be pretty large, it should be good to implement resuming. I've read the standard, but it's pretty long and allows for some flexibility. Since I need to get it done quickly, I'd prefer a stable, tested implementation of this feature.

                  谁能告诉我这样的脚本?

                  Can anyone point me to such a a script?

                  推荐答案

                  似乎我自己找到了我需要的东西.为了让其他人可以从中受益,这里是链接:http://www.coneural.org/florian/papers/04_byteserving.php

                  Seems that I found what I needed myself. So that other may benefit from this, here is the link: http://www.coneural.org/florian/papers/04_byteserving.php

                  以防万一原始页面停止工作(脚本已经很旧了),这里是它的副本:

                  And just in case the original page stops to work (the script is pretty old already), here is a copy of it:

                  <?php 
                  /*
                  
                  The following byte serving code is (C) 2004 Razvan Florian. You may find the latest version at 
                  http://www.coneural.org/florian/papers/04_byteserving.php
                  
                  */
                  function set_range($range, $filesize, &$first, &$last){
                    /*
                    Sets the first and last bytes of a range, given a range expressed as a string 
                    and the size of the file.
                  
                    If the end of the range is not specified, or the end of the range is greater 
                    than the length of the file, $last is set as the end of the file.
                  
                    If the begining of the range is not specified, the meaning of the value after 
                    the dash is "get the last n bytes of the file".
                  
                    If $first is greater than $last, the range is not satisfiable, and we should 
                    return a response with a status of 416 (Requested range not satisfiable).
                  
                    Examples:
                    $range='0-499', $filesize=1000 => $first=0, $last=499 .
                    $range='500-', $filesize=1000 => $first=500, $last=999 .
                    $range='500-1200', $filesize=1000 => $first=500, $last=999 .
                    $range='-200', $filesize=1000 => $first=800, $last=999 .
                  
                    */
                    $dash=strpos($range,'-');
                    $first=trim(substr($range,0,$dash));
                    $last=trim(substr($range,$dash+1));
                    if ($first=='') {
                      //suffix byte range: gets last n bytes
                      $suffix=$last;
                      $last=$filesize-1;
                      $first=$filesize-$suffix;
                      if($first<0) $first=0;
                    } else {
                      if ($last=='' || $last>$filesize-1) $last=$filesize-1;
                    }
                    if($first>$last){
                      //unsatisfiable range
                      header("Status: 416 Requested range not satisfiable");
                      header("Content-Range: */$filesize");
                      exit;
                    }
                  }
                  
                  function buffered_read($file, $bytes, $buffer_size=1024){
                    /*
                    Outputs up to $bytes from the file $file to standard output, $buffer_size bytes at a time.
                    */
                    $bytes_left=$bytes;
                    while($bytes_left>0 && !feof($file)){
                      if($bytes_left>$buffer_size)
                        $bytes_to_read=$buffer_size;
                      else
                        $bytes_to_read=$bytes_left;
                      $bytes_left-=$bytes_to_read;
                      $contents=fread($file, $bytes_to_read);
                      echo $contents;
                      flush();
                    }
                  }
                  
                  function byteserve($filename){
                    /*
                    Byteserves the file $filename.  
                  
                    When there is a request for a single range, the content is transmitted 
                    with a Content-Range header, and a Content-Length header showing the number 
                    of bytes actually transferred.
                  
                    When there is a request for multiple ranges, these are transmitted as a 
                    multipart message. The multipart media type used for this purpose is 
                    "multipart/byteranges".
                    */
                  
                    $filesize=filesize($filename);
                    $file=fopen($filename,"rb");
                  
                    $ranges=NULL;
                    if ($_SERVER['REQUEST_METHOD']=='GET' && isset($_SERVER['HTTP_RANGE']) && $range=stristr(trim($_SERVER['HTTP_RANGE']),'bytes=')){
                      $range=substr($range,6);
                      $boundary='g45d64df96bmdf4sdgh45hf5';//set a random boundary
                      $ranges=explode(',',$range);
                    }
                  
                    if($ranges && count($ranges)){
                      header("HTTP/1.1 206 Partial content");
                      header("Accept-Ranges: bytes");
                      if(count($ranges)>1){
                        /*
                        More than one range is requested. 
                        */
                  
                        //compute content length
                        $content_length=0;
                        foreach ($ranges as $range){
                          set_range($range, $filesize, $first, $last);
                          $content_length+=strlen("
                  --$boundary
                  ");
                          $content_length+=strlen("Content-type: application/pdf
                  ");
                          $content_length+=strlen("Content-range: bytes $first-$last/$filesize
                  
                  ");
                          $content_length+=$last-$first+1;          
                        }
                        $content_length+=strlen("
                  --$boundary--
                  ");
                  
                        //output headers
                        header("Content-Length: $content_length");
                        //see http://httpd.apache.org/docs/misc/known_client_problems.html for an discussion of x-byteranges vs. byteranges
                        header("Content-Type: multipart/x-byteranges; boundary=$boundary");
                  
                        //output the content
                        foreach ($ranges as $range){
                          set_range($range, $filesize, $first, $last);
                          echo "
                  --$boundary
                  ";
                          echo "Content-type: application/pdf
                  ";
                          echo "Content-range: bytes $first-$last/$filesize
                  
                  ";
                          fseek($file,$first);
                          buffered_read ($file, $last-$first+1);          
                        }
                        echo "
                  --$boundary--
                  ";
                      } else {
                        /*
                        A single range is requested.
                        */
                        $range=$ranges[0];
                        set_range($range, $filesize, $first, $last);  
                        header("Content-Length: ".($last-$first+1) );
                        header("Content-Range: bytes $first-$last/$filesize");
                        header("Content-Type: application/pdf");  
                        fseek($file,$first);
                        buffered_read($file, $last-$first+1);
                      }
                    } else{
                      //no byteserving
                      header("Accept-Ranges: bytes");
                      header("Content-Length: $filesize");
                      header("Content-Type: application/pdf");
                      readfile($filename);
                    }
                    fclose($file);
                  }
                  
                  function serve($filename, $download=0){
                    //Just serves the file without byteserving
                    //if $download=true, then the save file dialog appears
                    $filesize=filesize($filename);
                    header("Content-Length: $filesize");
                    header("Content-Type: application/pdf");
                    $filename_parts=pathinfo($filename);
                    if($download) header('Content-disposition: attachment; filename='.$filename_parts['basename']);
                    readfile($filename);
                  }
                  
                  //unset magic quotes; otherwise, file contents will be modified
                  set_magic_quotes_runtime(0);
                  
                  //do not send cache limiter header
                  ini_set('session.cache_limiter','none');
                  
                  
                  $filename='myfile.pdf'; //this is the PDF file that will be byteserved
                  byteserve($filename); //byteserve it!
                  ?>
                  

                  这篇关于PHP中是否有很好的实现部分文件下载?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  上一篇:支持简历的 PHP 远程文件流传输 下一篇:如何使用 PHP 创建 ZIP 文件并在用户下载后将其删除?

                  相关文章

                  <small id='uhezd'></small><noframes id='uhezd'>

                  <legend id='uhezd'><style id='uhezd'><dir id='uhezd'><q id='uhezd'></q></dir></style></legend>
                • <tfoot id='uhezd'></tfoot>

                    • <bdo id='uhezd'></bdo><ul id='uhezd'></ul>
                    <i id='uhezd'><tr id='uhezd'><dt id='uhezd'><q id='uhezd'><span id='uhezd'><b id='uhezd'><form id='uhezd'><ins id='uhezd'></ins><ul id='uhezd'></ul><sub id='uhezd'></sub></form><legend id='uhezd'></legend><bdo id='uhezd'><pre id='uhezd'><center id='uhezd'></center></pre></bdo></b><th id='uhezd'></th></span></q></dt></tr></i><div id='uhezd'><tfoot id='uhezd'></tfoot><dl id='uhezd'><fieldset id='uhezd'></fieldset></dl></div>