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.