• <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中是否有很好的实现部分文件下载?

        Is there a good implementation of partial file downloading in PHP?(PHP中是否有很好的实现部分文件下载?)
        • <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中是否有很好的实现部分文件下载?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

                  相关文档推荐

                  Is PHP or PHP based web framework stateful or stateless?(PHP 或基于 PHP 的 Web 框架是有状态的还是无状态的?)
                  How to parse django style template tags(如何解析 django 样式模板标签)
                  What is a good setup for editing PHP in Emacs?(在 Emacs 中编辑 PHP 的好设置是什么?)
                  How to check whether specified PID is currently running without invoking ps from PHP?(如何在不从 PHP 调用 ps 的情况下检查指定的 PID 当前是否正在运行?)
                  What#39;s the difference between escapeshellarg and escapeshellcmd?(escapeshellarg 和escapeshellcmd 有什么区别?)
                  php in background exec() function(php 后台 exec() 函数)

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

                  <legend id='uhezd'><style id='uhezd'><dir id='uhezd'><q id='uhezd'></q></dir></style></legend>
                    <tbody id='uhezd'></tbody>
                  <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>