ホームページ  >  記事  >  バックエンド開発  >  PHPでファイルをダウンロードする

PHPでファイルをダウンロードする

王林
王林オリジナル
2023-05-24 09:11:105915ブラウズ

Web サイトやアプリケーションを開発する場合、ファイルのダウンロード機能を実装する必要があることがよくありますが、これは PHP を使用して簡単に実装できます。この記事ではPHPを使ってファイルダウンロード機能を実装する方法を紹介します。

1. ファイルのダウンロード プロセス

ファイルをダウンロードする前に、ダウンロード プロセスを理解する必要があります:

  1. ユーザーは Web ページ上のダウンロード ボタンをクリックするか、アプリケーション;
  2. サーバーはダウンロード要求を受け入れます;
  3. サーバーはユーザーの権限とファイルの存在を確認します;
  4. サーバーはユーザーにファイルを送信します;
  5. ユーザーはファイルを受け取り、保存します。

2. ファイルのダウンロードの準備

PHP では、readfile 関数を使用してファイルの内容を読み取り、ブラウザに出力できます。ただし、ファイルが存在することを確認する必要があります。存在しないと例外がスローされます。以下は簡単なコード例です:

$file_path = '/path/to/your/file/yourfile.extension';
if (file_exists($file_path))
{
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename=' . basename($file_path));
    header('Content-Transfer-Encoding: binary');
    header('Content-Length: ' . filesize($file_path));
    readfile($file_path);
    exit;
}
else
{
    die('File not found.');
}

上記のコードでは、最初に file_exists 関数を使用してファイルが存在するかどうかを確認します。ファイルが存在する場合は、HTTP ヘッダー ファイルを設定して、ファイルがあることをブラウザに伝えます。をダウンロードしようとしており、Content の -Disposition にファイル名を指定し、Content-Type にファイルの種類を指定して、readfile 関数を使用してファイルの内容を出力します。

3. ファイルのダウンロードがリンクの盗用を防ぐ

ブラウザの性質上、一部の悪質なサイトがファイルを盗む可能性があるため、ファイルのダウンロードがリンクの盗用を防ぐ必要があります。

次のコードを追加して、ファイルのダウンロードが盗まれるのを防ぐことができます:

$referer = $_SERVER['HTTP_REFERER'];
if ($referer && !preg_match('/^https?://' . $_SERVER['SERVER_NAME'] . '/', $referer))
{
    header("HTTP/1.1 403 Forbidden");
    die("Access denied.");
}

このコードは、HTTP_REFERER ヘッダー情報をチェックし、それが現在のサーバーのドメイン名と一致することを確認します。一致しない場合は、403 ステータス コードが返され、アクセスが禁止されます。

4. 分割ダウンロードの実装

大きなファイルをダウンロードする場合、ダウンロード速度を向上させ、ネットワーク帯域幅の使用量を削減するために、分割ダウンロード機能を実装する必要がある場合があります。 HTTP 1.1 の Range ヘッダー情報を利用すると、セグメント化されたダウンロードを簡単に実装できます。

以下はサンプルコードです:

$file_path = '/path/to/your/file/yourfile.extension';
if (file_exists($file_path))
{
    $size = filesize($file_path);
    $start = 0;
    $end = $size - 1;
    
    if (isset($_SERVER['HTTP_RANGE']))
    {
        if (preg_match('/bytes=h*(d+)-(d*)[D.*]?/i', $_SERVER['HTTP_RANGE'], $matches))
        {
            $start = intval($matches[1]);
            if (!empty($matches[2]))
            {
                $end = intval($matches[2]);
            }
        }
    }
    if ($start > $end || $end > $size - 1 || $start < 0)
    {
        header('HTTP/1.1 416 Requested Range Not Satisfiable');
        header("Content-Range: bytes $start-$end/$size");
        exit;
    }
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename=' . basename($file_path));
    header('Content-Transfer-Encoding: binary');
    header("Content-Range: bytes $start-$end/$size");
    header('Accept-Ranges: bytes');
    header('Content-Length: ' . ($end - $start + 1));
    header("Cache-control: private");
    header('Pragma: private');
    header('Expires: ' . gmdate('D, d M Y H:i:s T', time() + 3600));
    
    $fp = fopen($file_path, 'rb');
    fseek($fp, $start);
    $buffer_size = 1024 * 8; //每次读取8 KB
    $bytes_send = 0;
    while (!feof($fp) && ($bytes_send < $end - $start + 1))
    {
        $buffer = fread($fp, $buffer_size);
        echo $buffer;
        flush();
        $bytes_send += strlen($buffer);
    }
    fclose($fp);
    exit;
}
else
{
    die('File not found.');
}

上記コードでは、まずHTTP_RANGEヘッダ情報を確認し、ヘッダ情報が存在しない場合はファイル全体を出力します。ヘッダー情報が存在する場合、開始オフセットと終了オフセットが解析され、fseek 関数を使用してファイル ポインターが特定され、fread 関数を使用してファイルの内容が読み取られてブラウザに出力されます。

5. 結論

PHP でファイルのダウンロード機能を実装することは、ファイルが存在するかどうかを確認し、正しい HTTP ヘッダー情報を設定するだけであり、それほど難しいことではありません。 HTTP 1.1 Range ヘッダー情報を使用すると、分割されたダウンロードを簡単に実現でき、盗まれたリンクからのファイルのダウンロードを防ぐことで、ファイルのセキュリティを保護できます。したがって、より良いユーザーエクスペリエンスを実現するために、ニーズに応じて必要な機能を実装することを選択できます。

以上がPHPでファイルをダウンロードするの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。