правильні PHP-заголовки для завантаження PDF-файлу -


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
Друкарська помилка? Спробуйте додати a ' $filename='./pdf/jobs/pdffile.pdf';і в цьому рядку header("Content-Disposition:inline;filename='$filename");відсутні лапки.
Funk Forty Niner

Як / чому ви використовуєте $url_download?
Funk Forty Niner

Відповіді:


135

Приклад 2 на w3schools показує, чого ви намагаєтесь досягти.

<?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.
Меттіс

readfile()дуже погано для великого розміру файлів, тому що коли деякі користувачі хочуть завантажити, кожен буфер завантаження файлів буфер на сервері RAM !!!
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замість цього.

Крім того, зробіть розширення файлу верхньою літерою, щоб зробити його сумісним з деякими мобільними пристроями. ( Оновлення : Практично впевнений, що ця проблема була лише у Blackberry, але світ перейшов від них, тож це може більше не турбувати)

Все сказане, ваш код повинен виглядати приблизно так:

<?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
Вам не потрібен закриваючий тег ?>. У цьому випадку його краще видалити.
Марсель Корпель

Цілком впевнений, що включення заголовка назви файлу в одинарні лапки всебічно порушує завантаження, тому, як ви припускаєте, це має велике значення.
Брайан С

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 (); вгорі забезпечує пошкодження даних
Ден Джей,

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));

І цей рядок помилковий:

заголовок ("Content-Disposition: вбудований; filename = '$ filename");

Ви переплутали квоти.


4
Ні, вам не потрібно вказувати розмір файлу. Це також можливе джерело помилок.
Марсель Корпель

Залежить від версії плагіна PDF. Давати його можна безпечно.
Flash Thunder

не можу змусити це працювати. Що таке змінна $ file, для якої я перевіряю розмір? Це URL-адреса файлу ./pdf/jobs/pdftitle.pdf?
useyourillusiontoo

так, це місце розташування файлу ... можливо, ви зіпсуєте шляхи? спробуйте дати абсолютний шлях.
Flash Thunder
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.