2010-12-28 15 views
2

大きなファイルをダウンロードするためのPHPスクリプトを書く必要があります。私がここに報告しているファイルは、ほとんどの場合、大丈夫です。しかし、クライアントの接続が遅い場合は、ダウンロードの途中で要求が終了し(ステータスコード200)、必ずしも同じ時点ではなく、同時にではありません。私はいくつかのphp.ini変数を上書きしようとしましたが(最初の文を見てください)、問題は残っています。 私はそれが適切かどうかわかりませんが、私のホスティングサーバーはSiteGroundです。単純な静的ファイル要求の場合、ダウンロードは低速接続でも正常に動作します。大きなファイルをダウンロードする

私はForced downloading large file with phpを見つけましたが、私はマリオの答えを理解しませんでした。私はウェブプログラミングに新しいです。

ここに私のコードです。

<?php 
    ini_set('memory_limit','16M'); 
    ini_set('post_max_size', '30M'); 
    set_time_limit(0); 

    include ('../private/database_connection.php'); 


    $downloadFolder = '../download/'; 
    $fileName = $_POST['file']; 
    $filePath = $downloadFolder . $fileName; 
    if($fileName == NULL) 
    { 
     exit; 
    } 
    ob_start(); 
    session_start(); 


    if(!isset($_SESSION['Username'])) 
    { 
     // or redirect to login (remembering this download request) 
     $_SESSION['previousPage'] = 'download.php?file=' . $fileName; 
     header("Location: login.php"); 
     exit; 
    } 

    if (file_exists($filePath)) 
    {    
     header('Content-Description: File Transfer'); 
     header('Content-Type: application/octet-stream'); 
     //header('Content-Disposition: attachment; filename='.$fileName); 
     header("Content-Disposition: attachment; filename=\"$fileName\""); 
     header('Content-Transfer-Encoding: binary'); 
     header('Expires: 0'); 
     header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); 
     //header('Pragma: public'); 
     header('Content-Length: ' . filesize($filePath)); 
     ob_clean(); 
     flush(); 

     // download 
     // 1 
//  readfile($filePath); 
     // 2 
     $file = @fopen($filePath,"rb"); 
     if ($file) { 
      while(!feof($file)) { 
      print(fread($file, 1024*8)); 
      flush(); 
      if (connection_status()!=0) { 
       @fclose($file); 
       die(); 
      } 
      } 
      @fclose($file); 
     } 
     exit; 
    } 
    else 
    { 
     header('HTTP/1.1 404 File not found'); 
     exit; 
    } 
?> 
+0

http://stackoverflow.com/questions/597159/sending-large-files-reliably-in-phpを見ると、 'X-SENDFILE'ヘッダーに関する回答が1つあります。ただし、ホストがこのヘッダーをサポートしているかどうかを確認してください。 – Joost

+0

私はそれが関連しているとは思わないが、私はASIHTTPRequestライブラリを使ってリクエストを行っています。私はASIFormDataRequestを構築し、downloadDestinationPathを設定します。 – dnaxxx

+0

x-sendfileは、レスポンスが即時に到着し、ステータスコード200でファイルがないためサポートされていないようです。私はそれを可能にすることができるかどうかSitegroundに尋ねるつもりです。 – dnaxxx

答えて

2

HTTPステータスコード200はすべて正常に実行されたことを意味します。

Content-Lengthが正しいことを確認し、connection_status()関数を使用しないで試してください。ユーザーが切断したことを不適切に報告している可能性があります。 PHPはconnection_aborted()の機能を持っています。

更新:あなたはマリオの答えについて尋ねたので、彼が何を意味するのは、サーバー上の実際のファイルにユーザーをリダイレクトし、あなたのサーバではなく、サーバがすでに何ができるかを複製しようとすると、それを処理させるべきであるということです。つまり、スクリプトを使用する代わりにheader("Location: " . $filePath)、またはファイルパスへのリンクを使用する必要があります。欠点は、添付ファイルのダウンロードを使用できないことですが、新しいウィンドウで開くことができます。同様の効果があります。

+0

あなたの答えにあなたのコメントを追加する必要があります。私はほぼ確実に何が起こるのかということは、接続にはビットフラグが設定されているため(おそらく待ち受けているため)、数字は0になりません。次に、あなたの答えに+1を与えます。 – sholsinger

+0

レスポンスのヘッダーを確認しましたが、内容の長さは正しいです。また、if文全体(connection_statusをチェックする)をコメントアウトしても、動作は変更されません。 – dnaxxx

+0

ファイルが公開されていないので、リダイレクトは機能しません(404を返します)。たぶん、他のトピックでは、マリオは回避策を提案していたが、それは私が理解できなかったものである。 ...私はまだ出発点です。おそらく私のホストに何か悪いことがありますか? – dnaxxx

関連する問題