1

私のローカルホストから画像をダウンロードするスクリプトを作成しようとしています。学校のプロジェクトのためだけに。

URL ("$_GET['file']") からファイル名を取得します。次に、このスクリプトを実行します。ファイルが破損して表示できなくなるたびに。画像をダウンロードしたいのですが、Word 文書を試してみると、これも破損していました。これは私のコードです:

<?php
//get file
$file = $_GET['file'];
//set path of file
$path = $_SERVER['DOCUMENT_ROOT']."/blackbox/mediafiles/"; 
$fullPath = $path.$file;
if ($fd = fopen ($fullPath, "r")) {
    $path_parts = pathinfo($fullPath);
        header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\""); // fore a download
        header("Content-type: application/octet-stream");
        header("Content-Disposition: filename=\"".$path_parts["basename"]."\"");
}
    header("Cache-control: private"); // open files directly
    while(!feof($fd)) {
        $buffer = fread($fd, 2048);
        echo $buffer;
    }
fclose ($fd);
exit;
?>

誰かが持っていて、何がうまくいかないのか考えていますか?

前もって感謝します!!

4

4 に答える 4

3

ファイルをバイナリ モードで明示的に開いてみます。

if ($fd = fopen ($fullPath, "rb")) {

fopenのドキュメントに次のように記載されています。

Windows は、ファイルを操作するときに透過的に \n を \r\n に変換するテキスト モード変換フラグ ('t') を提供します。対照的に、「b」を使用して、データを変換しないバイナリ モードを強制することもできます。これらのフラグを使用するには、モード パラメータの最後の文字として「b」または「t」を指定します。

デフォルトの変換モードは、使用している SAPI と PHP のバージョンに依存するため、移植性の理由から常に適切なフラグを指定することをお勧めします。プレーンテキスト ファイルを操作していて、\n を使用してスクリプト内の行末を区切っている場合は、't' モードを使用する必要がありますが、メモ帳などのアプリケーションでファイルを読み取れることを期待してください。それ以外の場合はすべて「b」を使用する必要があります。

バイナリ ファイルを操作するときに 'b' フラグを指定しないと、破損したイメージ ファイルや \r\n 文字に関する奇妙な問題など、データに奇妙な問題が発生する可能性があります。

于 2012-06-28T12:11:47.060 に答える
1

最初はあなたの答えではありません。しかし、PHPのセキュリティを実際に検討する必要があります。スクリプトでは、GETパラメータとDOCUMENT_ROOTを介してすべてのファイルにアクセスできます。

ユーザーを信用しないでください。

変数をユーザーに配信する前に、最初に変数をフィルター処理するか、既知のファイルリストにマップする必要があります。

PHPSec

于 2012-06-28T12:16:49.833 に答える
1

ファイルを手動で読み取って出力する代わりに、readfileを使用できます。

また、$_GET['file'] には '../' が含まれている可能性があり、セキュリティ リスクである任意のファイルを開くことができることに注意してください。basename関数を使用する(すべてのファイルが同じディレクトリにある場合)、または mediafiles ディレクトリ外のファイルへのアクセスを制限する

<?php
//get file
$file = $_GET['file'];
//set path of file
$path = $_SERVER['DOCUMENT_ROOT']."/blackbox/mediafiles/"; 
$fullPath = $path. basename($file);
if (is_readable($fullPath) {
    $path_parts = pathinfo($fullPath);
    header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\""); // fore a download
    header("Content-type: application/octet-stream");
    header("Content-length: " . filesize($fullPath));
    header("Content-Disposition: filename=\"".$path_parts["basename"]."\"");
    header("Cache-control: private"); // open files directly
    readfile($fullPath);
}
exit;
?>
于 2012-06-28T12:12:09.180 に答える
1

何かが PHP からエラーを投げているか、ファイル ( ) の開始タグの前に空白があります<?php

次の 2 つのことを行います。

  • <of<?phpがファイルの最初の文字であることを確認してください。スクリプトにバイト オーダー マーカーが含まれていないことを確認してください。
  • 次の行をスクリプトの先頭に追加します。error_reporting(0); ini_set('display_errors', 0);

エラーを無効にすることで問題が解決する場合は、修正が必要なエラーがあることを意味し、問題の最終的な解決策ではないことに注意してください。

また、ファイル ポインターを開いてループするよりも、使用するreadfile()方が短く、安全で、効率的です。

于 2012-06-28T12:13:04.047 に答える