2012-02-27 3 views
0

小さなスクリプトは、get文字列に基づいて、ユーザに2つの.pdfファイルのいずれかを送信するために使用されている:PHPのReadFile関数は動作しませんが、唯一のための20+メガのファイルは、

if ($fileToSend == "bigone") { 
    $filename = "largefile.pdf"; 
    $header = "application/pdf"; 
} else if ($fileToSend == "smallone") { 
    $filename = "smallfile.pdf"; 
    $header = "application/pdf"; 
} 
if (file_exists('d/' . $filename)){ 
    header('Content-type: ' . $header); 
    header('Content-disposition: attachment; filename=' . $filename); 
    readfile('d/' . $filename); 
} else { 
    echo('No good'); 
} 

どちらのファイルをD/smallfile.pdfとd/largefile.pdfが存在します。 smallfile.pdfは約5メガバイトです。 largefile.pdfは約25メガバイトです。

sendFile.php?fileToSend = smallone works。

sendFile.php?fileToSend = bigoneは機能しません。 FFで、それは

ファイルFirefoxは[URL] /sendFile.php?fileToSend=bigone

何のファイル名のエラーはありませんで、ファイルを見つけることができません を見つけていないと言います。

I)は、(フラッシュを追加

  • を試みました。 readfileの前に。これにより、ダウンロードファイルのダイアログボックスが表示されますが、0バイトのファイルが表示されます。
  • flush()を追加しています。 readfileの前に、header( 'Content-Length:'。filesize( 'd /'。$ filename))を追加します。 - これは正常に動作しますが、処理に2分ほどかかってしまいます(URLにヒットしても、2分近くは何も起こらず、ダイアログボックスに実際のファイルが正しくダウンロードされて表示されます)。

ご協力いただければ幸いです。 Jon

+0

PHPのメモリ制限を増やしてみましたか? – F21

+0

いいえ。面白い考え。それはこの現象を引き起こすだろうか?私は私の管理者に尋ねます。 – Jon

+1

許可されている場合は、 'ini_set'を使用してこれを自分で行うこともできます。 '' ini_set( 'memory_limit'、 '128M'); ' – F21

答えて

2

はい、あなたの問題はあなたにファイルを送りながら、この治療薬は、60年代の後ので文句を言わないタイムアウトメモリとset_time_limit(0);をかむしないようにあなたの塊を供給することである可能性が高いPHPのタイミングアウトです:

<?php 
if(isset($_GET['fileToSend'])){ 

    switch($_GET['fileToSend']){ 
     case "bigone": 
      if(downloadFile("./d/largefile.pdf")===false){ 
       //failed, do somthing 
      } 
      break; 

     case "smallone": 
      if(downloadFile("./d/smallfile.pdf")===false){ 
       //failed, do something 
      } 
      break; 

     default: 
      echo 'No file selected'; 
      break; 

    } 

} 

function downloadFile($file){ 
    if (file_exists($file)) { 
     if(is_dir($file)){return false;} 
     header('Content-Description: File Transfer'); 
     header('Content-Type: application/octet-stream'); 
     header('Content-Disposition: attachment; filename="'.basename($file)).'"'; 
     header('Content-Transfer-Encoding: binary'); 
     header('Connection: Keep-Alive'); 
     header('Expires: 0'); 
     header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); 
     header('Pragma: public'); 
     header('Content-Length: ' . filesize($file)); 

     ob_clean(); 
     $handle = fopen($file, "rb"); 
     $chunksize=(filesize($file)/1024); 

     set_time_limit(0); 
     while (!feof($handle)) { 
      echo fgets($handle, $chunksize); 
      flush(); 
     } 
     fclose($handle); 
     die; 
    }else{ 
     return false; 
    } 
} 
?> 
+0

ローレンス - 私はそのショットを与えるでしょう。それは価値があるため、File not foundが即座に返されるので、タイムアウトの問題ではないかとは思いますが、試してみます。 – Jon

+0

ロックンロール。これは完全に機能しました。ありがとうローレンス! – Jon

+0

チャンクサイズ「1024」を変更することで、ダウンロード速度を制限することもできます。 –

0

ダウンロードに時間がかかり、PHPスクリプトのタイムアウトに遭うことはありますか?

可能な場合は、適切なファイルにリダイレクトして、Webサーバーで直接処理させるようにすることをお勧めします。

<?php header('Location: http://www.example.com/d/' . $filename) ;?> 
+0

いくつかの理由から(私はユーザー名とユニークなトークンによって保護されているので、Googleをクロールしたくないので) 。 – Jon

0

ファイルをストリーミングするときは、出力バッファリングが無効になっていることを確認してください。それ以外の場合は、ファイル全体をバッファリングします。あなたのケースでは、ファイル全体をバッファリングしているため、PHPのメモリが不足している可能性があります。 ob_clean、フラッシュ前のReadFile追加:それはデータを受信して​​いるとして、それはする必要がある場合は、ダウンロードが10分を取ることができるように

ob_clean(); 
flush(); 
readfile('d/' . $filename); 

ブラウザは、限り、タイムアウトはありません。