programing

PHP를 사용하여 파일 강제 다운로드

sourcejob 2023. 7. 23. 14:12
반응형

PHP를 사용하여 파일 강제 다운로드

서버에 CSV 파일이 있습니다.사용자가 링크를 클릭하면 다운로드해야 하지만 브라우저 창에 링크가 열립니다.

제 코드는 다음과 같습니다.

<a href="files/csv/example/example.csv">
    Click here to download an example of the "CSV" file
</a>

이것은 제가 개발한 모든 작업이 있는 일반적인 웹 서버입니다.

저는 다음과 같은 것을 시도했습니다.

<a href="files/csv/example/csv.php">
    Click here to download an example of the "CSV" file
</a>

이제 나의 내용은csv.php파일:

header('Content-Type: application/csv');
header('Content-Disposition: attachment; filename=example.csv');
header('Pragma: no-cache');

문제는 CSV 파일이 다운로드된다는 것입니다.새 파일을 만듭니다.

.htaccess 솔루션

서버의 모든 CSV 파일을 강제로 다운로드하려면 .htaccess 파일에 다음을 추가합니다.

AddType application/octet-stream csv

PHP 솔루션

header('Content-Type: application/csv');
header('Content-Disposition: attachment; filename=example.csv');
header('Pragma: no-cache');
readfile("/path/to/yourfile.csv");

또는 HTML5를 사용하여 이 작업을 수행할 수 있습니다. 간단히

<a href="example.csv" download>download not open it</a>

검색을 요청한 URL로 무엇을 할지 결정하는 것은 브라우저에 달려 있기 때문에 이 작업은 안정적으로 수행될 수 없습니다.

내용-처리 헤더를 보내 "디스크에 저장"을 즉시 제공해야 한다고 브라우저에 제안할 수 있습니다.

header("Content-disposition: attachment");

이것이 다양한 브라우저에서 얼마나 잘 지원되는지 잘 모르겠습니다.다른 방법은 콘텐츠 유형의 응용 프로그램/옥텟 스트림을 보내는 것이지만, 이는 해킹(기본적으로 대부분의 브라우저가 다운로드 대화 상자를 제공한다는 사실에 따라 브라우저에 "이것이 어떤 종류의 파일인지 알려주지 않습니다"라고 말합니다)이며 Internet Explorer에 문제를 일으키는 것으로 알려져 있습니다.

자세한 내용은 웹 저작 FAQ를 참조하십시오.

편집 데이터를 전송하기 위해 이미 PHP 파일로 전환했습니다. 이 파일은 콘텐츠 처리 헤더를 설정하는 데 필요합니다(이를 수행할 수 있는 난해한 Apache 설정이 없는 경우).이제 남은 일은 PHP 파일이 CSV 파일의 내용을 읽고 인쇄하는 것입니다.filename=example.csv헤더는 클라이언트 브라우저에 파일에 사용할 이름만 제공하며 실제로는 서버의 파일에서 데이터를 가져오지 않습니다.

다음은 보다 안전한 브라우저 솔루션입니다.

    $fp = @fopen($yourfile, 'rb');

    if (strstr($_SERVER['HTTP_USER_AGENT'], "MSIE"))
{
    header('Content-Type: "application/octet-stream"');
    header('Content-Disposition: attachment; filename="yourname.file"');
    header('Expires: 0');
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    header("Content-Transfer-Encoding: binary");
    header('Pragma: public');
    header("Content-Length: ".filesize($yourfile));
}
else
{
    header('Content-Type: "application/octet-stream"');
    header('Content-Disposition: attachment; filename="yourname.file"');
    header("Content-Transfer-Encoding: binary");
    header('Expires: 0');
    header('Pragma: no-cache');
    header("Content-Length: ".filesize($yourfile));
}

fpassthru($fp);
fclose($fp);

미디어 유형과 함께 파일을 보내도록 서버 구성application/octet-stream.

즉, 브라우저에서 이 파일 형식을 처리할 수 있습니다.

마음에 들지 않으면 ZIP 파일을 제공하는 것이 가장 쉬운 방법입니다.모든 사용자가 ZIP 파일을 처리할 수 있으며 기본적으로 다운로드할 수 있습니다.

깨끗하고 좋은 솔루션:

<?php
    header('Content-Type: application/download');
    header('Content-Disposition: attachment; filename="example.csv"');
    header("Content-Length: " . filesize("example.csv"));

    $fp = fopen("example.csv", "r");
    fpassthru($fp);
    fclose($fp);
?>

이 페이지의 이전 답변에서는 .htaccess를 사용하여 특정 유형의 모든 파일을 강제로 다운로드하는 방법에 대해 설명합니다.그러나 이 솔루션이 모든 브라우저의 모든 파일 형식에서 작동하는 것은 아닙니다.이 방법이 더 안정적입니다.

<FilesMatch "\.(?i:csv)$">
  ForceType application/octet-stream
  Header set Content-Disposition attachment
</FilesMatch>

올바르게 작동하려면 브라우저 캐시를 플러시해야 할 수 있습니다.

응용 프로그램 자체를 사용하여 수행하는 경우이 코드가 도움이 되길 바랍니다.

HTML

Href - URL과 함께 download_file.php를 추가해야 합니다.

<a class="download" href="'/download_file.php?fileSource='+http://www.google.com/logo_small.png" target="_blank" title="YourTitle">

PHP

/* Here is the Download.php file to force download stuff */

<?php
    $fullPath = $_GET['fileSource'];
    if($fullPath) {
        $fsize = filesize($fullPath);
        $path_parts = pathinfo($fullPath);
        $ext = strtolower($path_parts["extension"]);

        switch ($ext) {
            case "pdf":
                header("Content-Disposition: attachment; filename=\"" . $path_parts["basename"]."\""); // Use 'attachment' to force a download
                header("Content-type: application/pdf"); // Add here more headers for diff. extensions
                break;

            default;
                header("Content-type: application/octet-stream");
                header("Content-Disposition: filename=\"" . $path_parts["basename"]."\"");
        }

        if($fsize) { // Checking if file size exist
            header("Content-length: $fsize");
        }
        readfile($fullPath);
        exit;
    }
?>

강제로 다운로드하려면 다음을 사용할 수 있습니다.Content-Type: application/octet-stream대부분의 브라우저에서 지원되는 헤더:

function downloadFile($filePath)
{
    header("Content-type: application/octet-stream");
    header('Content-Disposition: attachment; filename="' . basename($filePath) . '"');
    header('Content-Length: ' . filesize($filePath));
    readfile($filePath);
}

더 나은 방법

이런 방식으로 파일을 다운로드하는 것은 특히 대용량 파일에 적합하지 않습니다.PHP는 파일 내용을 읽고 출력하기 위해 추가 CPU/메모리가 필요하며 대용량 파일을 처리할 때 시간/메모리 제한에 도달할 수 있습니다.

더 나은 방법은 PHP를 사용하여 파일을 인증하고 파일에 대한 액세스 권한을 부여하는 것이며 실제 파일 서빙은 X-SENDFILE 방법을 사용하여 웹 서버에 위임해야 합니다(일부 웹 서버 구성 필요).

  • X-SENDFILE기본적으로 Lighttpd: https://redmine.lighttpd.net/projects/1/wiki/X-LIGHTTPD-send-file 에서 지원됩니다.
  • 가 필요합니다.mod_xsendfile모듈: https://tn123.org/mod_xsendfile/ Ubuntu에는 다음 사용자가 설치할 수 있습니다.apt install libapache2-mod-xsendfile
  • Nginx 유니다사합는을 가지고 있습니다.X-Accel-Redirect헤더: https://www.nginx.com/resources/wiki/start/topics/examples/xsendfile/

를 하도록 웹 한 후X-SENDFILE그냥 대체합니다.readfile($filePath)와 함께header('X-SENDFILE: ' . $filePath)웹는 PHP를 보다 적은 를 필요로 서빙을입니다.readfile.

사용(Nginx용))X-Accel-Redirect 헤더X-SENDFILE)

파일을 웹 입니다.X-SENDFILE서버를 하십시오.웹 서버를 올바르게 구성하는 방법을 보려면 위의 링크를 확인하십시오.

언급URL : https://stackoverflow.com/questions/1465573/forcing-to-download-a-file-using-php

반응형