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로 무엇을할지 결정하는 것은 브라우저의 몫이기 때문에 이것은 안정적으로 수행 될 수 없습니다.
Content-disposition 헤더를 전송하여 즉시 "디스크에 저장"을 제공하도록 브라우저에 제안 할 수 있습니다 .
header("Content-disposition: attachment");
다양한 브라우저에서 이것이 얼마나 잘 지원되는지 잘 모르겠습니다. 대안은 애플리케이션 / 옥텟 스트림의 콘텐츠 유형을 보내는 것입니다.하지만 그것은 해킹입니다 (기본적으로 브라우저에 "이 파일의 종류를 말하지 않습니다"라고 말하고 대부분의 그러면 브라우저가 다운로드 대화 상자를 제공하고 Internet Explorer에 문제를 일으킨다 고합니다.
웹 작성 FAQ 에서 이에 대한 자세한 내용을 읽어보십시오 .
편집 이미 데이터를 전달하기 위해 PHP 파일로 전환했습니다. 이는 Content-disposition 헤더를 설정하는 데 필요합니다 (이를 수행 할 수있는 일부 아파치 설정이없는 경우). 이제 남은 일은 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);
?>
A previous answer on this page describes how to use .htaccess to force all files of a certain type to download. However, the solution does not work with all file types across all browsers. This is a more reliable way:
<FilesMatch "\.(?i:csv)$">
ForceType application/octet-stream
Header set Content-Disposition attachment
</FilesMatch>
You might need to flush your browser cache to see this working correctly.
If you are doing it with your application itself... I hope this code helps.
HTML
In href -- you have to add download_file.php along with your URL:
<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;
}
?>
To force download you may use Content-Type: application/force-download
header, which is supported by most browsers:
function downloadFile($filePath)
{
header("Content-type: application/octet-stream");
header('Content-Disposition: attachment; filename="' . basename($filePath) . '"');
header('Content-Length: ' . filesize($filePath));
readfile($filePath);
}
A BETTER WAY
Downloading files this way is not the best idea especially for large files. PHP will require extra CPU / Memory to read and output file contents and when dealing with large files may reach time / memory limits.
A better way would be to use PHP to authenticate and grant access to a file, and actual file serving should be delegated to a web server using X-SENDFILE method (requires some web server configuration):
X-SENDFILE
is natively supported by Lighttpd: https://redmine.lighttpd.net/projects/1/wiki/X-LIGHTTPD-send-file- Apache requires
mod_xsendfile
module: https://tn123.org/mod_xsendfile/ On Ubuntu may be installed by:apt install libapache2-mod-xsendfile
- Nginx has a similar
X-Accel-Redirect
header: https://www.nginx.com/resources/wiki/start/topics/examples/xsendfile/
After configuring web server to handle X-SENDFILE
, just replace readfile($filePath)
with header('X-SENDFILE: ' . $filePath)
and web server will take care of file serving, which will require less resources than using PHP readfile
.
(For Nginx use X-Accel-Redirect
header instead of X-SENDFILE
)
Note: If you end up downloading empty files, it means you didn't configure your web server to handle X-SENDFILE
header. Check the links above to see how to correctly configure your web server.
참고URL : https://stackoverflow.com/questions/1465573/forcing-to-download-a-file-using-php
'developer tip' 카테고리의 다른 글
React-Router 외부 링크 (0) | 2020.11.26 |
---|---|
XSLT에서 HTML 엔티티 사용 (예 :) (0) | 2020.11.26 |
옵션의 텍스트 / 값이 주어지면 드롭 다운 목록에서 옵션을 제거하는 jQuery (0) | 2020.11.26 |
Java의 플랫폼 독립 경로 (0) | 2020.11.26 |
PostgreSQL에서 임시 함수를 만드는 방법은 무엇입니까? (0) | 2020.11.26 |