14

必要なjavascriptタイマーの後に、phpスクリプトを使用してWebサイトからのダウンロードを提供しています。このphpスクリプトが含まれているため、ダウンロードが発生します。しかし、ダウンロードしたファイルは、何を試しても破損しています。誰かが私がどこで間違っているのかを指摘するのを手伝ってくれますか?

これは私のコードです

     <?php
include "db.php";    
 $id = htmlspecialchars($_GET['id']);
 $error = false;
    $conn = mysql_connect(DB_HOST,DB_USER,DB_PASSWORD);
    if(!($conn)) echo "Failed To Connect To The Database!";
    else{   
        if(mysql_select_db(DB_NAME,$conn)){
            $qry = "SELECT Link FROM downloads WHERE ID=$id";
            try{
                $result = mysql_query($qry);
                if(mysql_num_rows($result)==1){
                    while($rows = mysql_fetch_array($result)){
                        $f=$rows['Link'];
                    }
                    //pathinfo returns an array of information
                    $path = pathinfo($f);
                    //basename say the filename+extension
                    $n = $path['basename'];
                    //NOW comes the action, this statement would say that WHATEVER output given by the script is given in form of an octet-stream, or else to make it easy an application or downloadable
                    header('Content-type: application/octet-stream');
                    header('Content-Length: ' . filesize($f));
                    //This would be the one to rename the file
                    header('Content-Disposition: attachment; filename='.$n.'');
                    //Finally it reads the file and prepare the output
                    readfile($f);
                    exit();
                }else $error = true;
            }catch(Exception $e){
                $error = true;
            }
            if($error) 
            {
                header("Status: 404 Not Found");
                }
        }
  }
?> 
4

3 に答える 3

27

これは、より多くの出力バッファーが開かれた場合に役立ちました。

//NOW comes the action, this statement would say that WHATEVER output given by the script is given in form of an octet-stream, or else to make it easy an application or downloadable
header('Content-type: application/octet-stream');
header('Content-Length: ' . filesize($f));
//This would be the one to rename the file
header('Content-Disposition: attachment; filename='.$n.'');
//clean all levels of output buffering
while (ob_get_level()) {
    ob_end_clean();
}
readfile($f);
exit();
于 2015-03-12T06:19:39.983 に答える
14

まず、コメントで指摘されているように<?php、最初の行のPHPタグ()を開く前にすべてのスペースを削除すると、うまくいくはずです(このファイルが他のファイルに含まれているか、必要とされている場合を除く)。

画面に何かを印刷すると、たとえ1つのスペースであっても、サーバーは印刷するコンテンツ(この場合は空白スペース)とともにヘッダーを送信します。これを防ぐために、次のことができます。

a)ヘッダーの書き込みが完了するまでは何も印刷しないでください。

b)スクリプトの最初にob_start()を実行し、コンテンツを書き込み、ヘッダーを編集してから、コンテンツをユーザーのブラウザーに送信するたびにob_flush()とob_clean()を実行します。

b)では、エラーが発生せずにヘッダーを正常に書き込んだとしても、スペースによってバイナリファイルが破損します。バイナリコンテンツを書き込むスペースは少なくなく、バイナリコンテンツのみを書き込む必要があります。

ob_プレフィックスは出力バッファを表しますを呼び出すときは、クライアントに「go」()を明示的に指示するまで、ob_start()出力するすべて(、、など)をメモリに保持するようにアプリケーションにecho指示します。そうすれば、ヘッダーと一緒に出力を保持し、それらを書き終えると、コンテンツと一緒に問題なく送信されます。printfob_flush()

于 2012-11-09T17:15:23.800 に答える
2
           ob_start();//add this to the beginning of your code 

      if (file_exists($filepath) && is_readable($filepath) ) {
header('Content-Description: File Transfer');
 header("Content-Type: application/octet-stream");
 header("Content-Disposition: attachment; filename=$files");
 header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
   header('Pragma: public');
 header("content-length=".filesize($filepath));
 header("Content-Transfer-Encoding: binary");

   /*add while (ob_get_level()) {
       ob_end_clean();
         }  before readfile()*/
  while (ob_get_level()) {
ob_end_clean();
   }
    flush();
   readfile($filepath);
于 2020-03-25T19:56:28.970 に答える