0

PHPを使用してサーバー上で生成された.zipファイルがあります。生成されたファイルは有効で、ftp などでダウンロードして確認しました。

このファイルが生成された後、ユーザーがこのファイルをダウンロードしてからファイルを削除する方法を作成する必要があります。ここに私が送信しているヘッダーがあります。

header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-control: public");
header("Content-Description: File Transfer");
header('Content-type: application/zip'); 
header("Content-Transfer-Encoding: Binary");
header('Content-Disposition: attachment; filename="'.basename($archive_file_name).'"');
header("Content-Length: " . filesize($this->dirPath."/".$archive_file_name) );
ob_clean();
//echo is_file($this->dirPath."/".$archive_file_name);
readfile($this->dirPath."/".$archive_file_name);
unlink($this->dirPath."/".$archive_file_name);
exit;

上記のコードは、最初の数回ダウンロードしようとすると機能しますが、数ターン後に.zipではなく.phpファイルとしてダウンロードを開始します

ファイルのダウンロードは、zip ファイルの作成を開始する特定のリンクに移動することによってトリガーされます。完了すると、ヘッダーを送信してダウンロードを開始します

4

2 に答える 2

1

あなたのコードは適切に見えます。ただし、コードの前後のスペースを確保する必要があります。
コードにヘッダーを追加すると、スペースが中断され、zip ファイルが読み込まれません。
もう一度確認して、ページの上下のスペースを削除してください。


readfile($this->dirPath."/".$archive_file_name);という行があります。
コードから削除できます

于 2013-04-09T06:32:18.007 に答える
0

履歴書でダウンロードできるこのヘッダーを試してみてください。データベースまたはログファイルを使用して、ダウンロードされたファイルを理解することをお勧めします。

ダウンローダからリクエスト範囲を取得 fseek を使用してファイルの範囲を読み取ることができます

$Range=@$_SERVER['HTTP_RANGE'];//Range: bytes=843530240-
$Cach="";
if($Range!=""){
  $Range=explode("=",$Range);
  $Cach=(int)trim($Range[1]," -");      
}

キャッシングコントローラー

function caching_include($file) {
     $headers = $_SERVER;
     // Get the modification timestamp
     if(!(list(,,,,,,,,,$lastModified) = @stat($file))){
           echo Error;
           exit();          
     }
     // Build our entity tag
     $eTag = "ci-".dechex(crc32($file.$lastModified));
     if (false and (strpos(@$headers['If-None-Match'], "$eTag")) &&(gmstrftime("%a, %d %b %Y %T %Z", $lastModified) == @$headers['If-Modified-Since'])) {
        // They already have an up to date copy so tell them
        header('HTTP/1.1 304 Not Modified');
        header('Cache-Control: private');
        header("Pragma: ");
        header('Expires: ');
        header('Content-Type: ');
        header('ETag: "'.$eTag.'"');
        exit;
     } else {
       // We have to send them the whole page
        header('Cache-Control: private');
        header('Pragma: ');
        header('Expires: ');
        header('Last-Modified: '.gmstrftime("%a, %d %b %Y %T %Z",$lastModified));
        header('ETag: "'.$eTag.'"');
     }
  }

ダウンロード用ヘッダー

header("Server: SepidarSoft/ir-system");//server name 
header("Date: ".date("a,d b Y H:M:S GMT",time()));
header("X-Powered-By: SepidarSoft");
header("Cache-Control: public");
header("Content-disposition:filename=\"".$BaseName."\"");//file name
caching_include($FPatch);//caching controller 
header("Accept-Ranges:bytes");
header("Content-Transfer-Encoding: binary\n"); 
header("Connection: Keep-Alive");
header("Content-Type: $Type");//file type like application/zip
header("Content-Length: ".($FSize-$Cach)); //length of download it is for resume  
header("Content-Range: bytes ".$Cach."-".($FSize-1)."/".$FSize); //download range it is for resume
header("HTTP/1.1 206 Partial Content",true);
set_time_limit(0);

コードで使用set_time_limit(0);する場合、ユーザー接続が切断された場合、PHP は作業が終了するまで続行し、ファイルが削除されます。ダウンロードするかどうかは、1 つの要求の後にconnection_status()==0次のような接続の確認に使用できます。

$Speed=102400;
fseek($Handle,$From);//if use resume it is useful 
while(!@feof($Handle) and (connection_status()==0)){
    print(fread($Handle,$Speed));
    flush(); 
            ob_flush(); 
 } 
 if(connection_status()==0){//with this condition you can understand download is down by user 
       unlink($this->dirPath."/".$archive_file_name);
 }   
于 2013-04-09T05:31:12.667 に答える