Принуждение к загрузке файла с помощью 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
file:
header('Content-Type: application/csv');
header('Content-Disposition: attachment; filename=example.csv');
header('Pragma: no-cache');
теперь моя проблема в том, что это загрузка, но не мой CSV-файл. Он создает новый файл.
10 ответов:
.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.
Edit вы уже переключились на PHP - файл для доставки данных, что необходимо для установки заголовка Content-disposition (если только нет некоторых тайных настроек 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);
Это означает, что ваш браузер может обрабатывать файлы этого типа.
Если вам это не нравится, самый простой способ будет предлагать 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-вы должны добавить download_file.php вместе с вашим 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; } ?>
для начала загрузки вы можете использовать
Content-Type: application/force-download
заголовок, который поддерживается большинством браузеров:function downloadFile($filePath) { header('Content-Type: application/force-download'); header('Content-Disposition: attachment; filename="' . basename($filePath) . '"'); header('Content-Length: ' . filesize($filePath)); readfile($filePath); }
ЛУЧШИЙ СПОСОБ
загрузка файлов таким образом не является лучшей идеей, особенно для больших файлов. PHP потребует дополнительного процессора / памяти для чтения и вывода содержимого файла, а при работе с большими файлами может достигать ограничений по времени / памяти.
лучшим способом было бы использовать PHP для аутентификации и предоставления доступа к файлу и фактическому файлу обслуживание должно быть делегировано веб-серверу с помощью метода X-SENDFILE (требуется некоторая конфигурация веб-сервера):
X-SENDFILE
изначально поддерживается Lighttpd:https://redmine.lighttpd.net/projects/1/wiki/X-LIGHTTPD-send-file- Apache требует
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)
и веб-сервер будет заботиться о обслуживании файлов, что потребует меньше ресурсов, чем использование PHPreadfile
.(для Nginx используйте
X-Accel-Redirect
заголовок вместоX-SENDFILE
)Примечание: Если вы в конечном итоге скачивание пустые файлы, это означает, что вы не настроили свой веб-сервер для обработки
X-SENDFILE
заголовок. Проверьте ссылки выше, чтобы увидеть, как правильно настроить веб-сервер.