pdf 파일 다운로드를위한 올바른 PHP 헤더


79

사용자가 링크를 클릭 할 때 내 응용 프로그램이 pdf를 열도록하는 데 정말 어려움을 겪고 있습니다.

지금까지 앵커 태그는 다음과 같은 헤더를 보내는 페이지로 리디렉션됩니다.

$filename='./pdf/jobs/pdffile.pdf;

$url_download = BASE_URL . RELATIVE_PATH . $filename;

header("Content-type:application/pdf");
header("Content-Disposition:inline;filename='$filename");
readfile("downloaded.pdf");

이것은 작동하지 않는 것 같습니다. 누군가 과거 에이 문제를 성공적으로 분류 한 적이 있습니까?


1
오식? ' $filename='./pdf/jobs/pdffile.pdf';이 줄에 header("Content-Disposition:inline;filename='$filename");누락 된 따옴표를 추가해보십시오 .
Funk Forty Niner 2013

어떻게 / 왜 사용하고 $url_download있습니까?
Funk Forty

답변:


135

w3schools의 예제 2 는 달성하려는 목표를 보여줍니다.

<?php
header("Content-type:application/pdf");

// It will be called downloaded.pdf
header("Content-Disposition:attachment;filename='downloaded.pdf'");

// The PDF source is in original.pdf
readfile("original.pdf");
?>

또한 기억하십시오.

실제 출력이 전송되기 전에 header ()가 호출되어야한다는 점에 유의하는 것이 중요합니다 (PHP 4 이상에서는 출력 버퍼링을 사용하여이 문제를 해결할 수 있습니다).


하하. 동일한 예가 있기 때문에 언급했습니다.
gat

출력 통지를 위해 1을 더합니다.
iamdash

5
파일 이름 주위의 작은 따옴표를 제거하는 것을 잊지 마십시오. filename = 'downloaded.pdf'를 사용하는 경우 일부 브라우저는 파일 이름에 따옴표가있는 파일을 저장하려고합니다. 나는 최근에 OSX에서 이것을 경험했습니다.
mattis

readfile()일부 사용자가 다운로드를 원할 때 각 다운로드 파일이 서버 램에 버퍼링되기 때문에 큰 파일 크기에 매우 나쁩니다 !!!
mghhgm

1
왜 PDF에 HTML 태그가 있을까요?
delboy1978uk

29
$name = 'file.pdf';
//file_get_contents is standard function
$content = file_get_contents($name);
header('Content-Type: application/pdf');
header('Content-Length: '.strlen( $content ));
header('Content-disposition: inline; filename="' . $name . '"');
header('Cache-Control: public, must-revalidate, max-age=0');
header('Pragma: public');
header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
echo $content;

2
전체 파일 내용을 변수로로드하면 메모리 제한과 충돌 할 수 있습니다. 이것이 readfile()선호되는 솔루션 인 이유 입니다.
Havenard

12

코드에서 고려해야 할 몇 가지 사항이 있습니다.

먼저 해당 헤더를 올바르게 작성하십시오. 를 보내는 서버를 볼 수 없으며 Content-type:application/pdf헤더는 Content-Type: application/pdf공백이고 대문자로 시작합니다.

의 파일 이름 Content-Disposition은 전체 경로가 아닌 파일 이름 뿐이며 필수인지 여부는 알 수 없지만이 이름은 " not '. 또한 마지막 '이 없습니다.

Content-Disposition: inline파일이 다운로드되는 것이 아니라 표시되어야 함을 의미합니다. attachment대신 사용하십시오 .

또한 일부 모바일 장치와 호환되도록 파일 확장자를 대문자로 만드십시오. ( 업데이트 : 블랙 베리 만이 문제가 있었지만 세상이 그 문제에서 옮겨 졌으므로 더 이상 걱정할 필요가 없습니다)

모든 말은 코드가 다음과 같이 보일 것입니다.

<?php

    $filename = './pdf/jobs/pdffile.pdf';

    $fileinfo = pathinfo($filename);
    $sendname = $fileinfo['filename'] . '.' . strtoupper($fileinfo['extension']);

    header('Content-Type: application/pdf');
    header("Content-Disposition: attachment; filename=\"$sendname\"");
    header('Content-Length: ' . filesize($filename));
    readfile($filename);

Content-Length선택 사항이지만 사용자가 다운로드 진행 상황을 추적하고 다운로드가 중단되었는지 감지 할 수 있도록하려는 경우에도 중요합니다. 그러나 그것을 사용할 때 파일 데이터와 함께 아무것도 보내지 않도록해야합니다. 빈 줄이 아니라 <?php앞뒤에 아무것도 없는지 확인하십시오 ?>.


3
닫는 태그가 필요하지 않습니다 ?>. 이 경우 제거하는 것이 좋습니다.
Marcel Korpel 2013

헤더가 제공하는 파일 이름을 작은 따옴표로 묶으면 다운로드가 포괄적으로 중단되므로 제안한대로 큰 차이가 있습니다.
Brian C

4

나는 최근에 같은 문제가 있었고 이것은 나를 도왔습니다.

    header('Content-Description: File Transfer'); 
    header('Content-Type: application/octet-stream'); 
    header('Content-Disposition: attachment; filename="FILENAME"'); 
    header('Content-Transfer-Encoding: binary'); 
    header('Expires: 0'); 
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); 
    header('Pragma: public'); 
    header('Content-Length: ' . filesize("PATH/TO/FILE")); 
    ob_clean(); 
    flush(); 
    readfile(PATH/TO/FILE);      
    exit();

여기 에서이 답변을 찾았 습니다.


2
ob_start (); 데이터 손상 보장
Dan Jay

1

이것을 시도 할 수 있습니까 readfile, 전체 파일 경로가 필요합니다.

        $filename='/pdf/jobs/pdffile.pdf';            
        $url_download = BASE_URL . RELATIVE_PATH . $filename;            

        //header("Content-type:application/pdf");   
        header("Content-type: application/octet-stream");                       
        header("Content-Disposition:inline;filename='".basename($filename)."'");            
        header('Content-Length: ' . filesize($filename));
        header("Cache-control: private"); //use this to open files directly                     
        readfile($filename);

0

파일 크기를 정의해야합니다 ...

header('Content-Length: ' . filesize($file));

그리고이 줄은 잘못되었습니다.

header ( "Content-Disposition : inline; filename = '$ filename");

할당량을 엉망으로 만들었습니다.


4
아니요, 파일 크기를 제공 할 필요가 없습니다. 그것은 또한 버그의 가능한 소스입니다.
Marcel Korpel 2013

PDF 플러그인 버전에 따라 다릅니다. 주는 것이 안전합니다.
Flash Thunder

이것을 작동시킬 수 없습니다. 크기를 테스트하는 $ file 변수는 무엇입니까? 파일 URL ./pdf/jobs/pdftitle.pdf입니까?
useyourillusiontoo

예, 파일 위치입니다 ... 경로를 엉망으로 만들고 있습니까? 절대 경로를 제공하십시오.
Flash Thunder
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.