Обслуживание загружаемых файлов с помощью PHP - PullRequest
2 голосов
/ 14 февраля 2012

Обычно для загружаемых с сервера файлов, которые находятся вне общедоступной папки с помощью PHP:

$fp = fopen($file,"r") ;
header("Content-Type: application/msword");
header('Content-Disposition: attachment; filename="'.$filename.'"');

while (! feof($fp)) {
    $buff = fread($fp,4096);
    echo $buff;
}

У меня два вопроса:

  1. Сравнение со статическими файлами, обслуживаемыми веб-сервером (прямой URL-адрес файла); нужен ли этому методу больше ресурсов (память и процессор), так как PHP должен прочитать файл и доставить?

  2. Как мы можем отобразить текст на странице? Как мы определили header, у нас нет вывода html скрипта php.

Ответы [ 4 ]

3 голосов
/ 14 февраля 2012
  1. Да, чтение файла с помощью PHP и запись его пользователю потребует больше памяти и процессора, конечно, в зависимости от размера файла.
  2. Сначала отобразите страницу, и на странице есть кнопка / ссылка, которая ведет пользователя к реальному сценарию загрузки.

Также я бы предложил использовать заголовок длины содержимого.

header('Content-Length: '. filesize($path));
2 голосов
/ 14 февраля 2012

1 Так как вы должны обработать файл с помощью этого скрипта, он требует больше ресурсы, чем просто обычная ссылка для скачивания. Однако это зависит от ваших потребностей. Если вы думаете, что эти файлы нуждаются в большей безопасности. Допустим, только аутентифицированные пользователи могут загрузить файл, и только файл принадлежит ему. Тогда вам нужно подтвердить это. В такой ситуации вам нужен код, который вы указали в своем вопросе. Если ваши файлы открыты для публики, то вы можете отобразить прямую ссылку на файл, возможно, разместив их где-нибудь публично временно.

2 Я могу предложить вам два способа сделать это.

Метод 1:

Вам необходима поддержка javascript для удобного выполнения такого рода требований. Предположим, вам нужно отобразить HTML-код на странице, где возможна загрузка. Вы можете создать страницу с нужным вам HTML-кодом и добавить кнопку загрузки.

<input type="button" name="cmdDownload" id="cmdDownload" value="Download" onclick="downloadFile('<?php echo $pathToTheFile; ?>');" />

И вы можете оставить скрытый iframe для обработки загрузки.

<iframe id="downloadFrame" style="display:none"></iframe>

Предположим, ваша страница загрузки PHP - download.php.

Тогда у вас может быть такая функция javascript.

<script type="text/javascript">
function downloadFile(filepath) 
{
    var ifrme = document.getElementById("downloadFrame");
    ifrme.src = "download.php?filepath="+filepath;
}
</script>

Метод 2:

Кроме метода, описанного выше, вы также можете использовать META Refresh.

<meta http-equiv="Refresh" content="3;URL=<?php echo $fullHTTPathToYourFile ?>" />

С этим вы также можете отображать HTML.

2 голосов
/ 14 февраля 2012
  1. Немного больше накладных расходов, чем непосредственное обслуживание файла, так как теперь вы используете PHP
  2. Нет, вы не можете. Если вы выводите (скажем) заголовок application / msword, то ВСЕ, что вы выводите ВСЕ, будет считаться частью файла .doc и вызывать его повреждение. Если вы хотите вывести некоторый текст, вы должны выполнить загрузку в две части - вывести стандартную HTML-страницу с текстом и включить временное перенаправление <meta> (или javascript), чтобы перенаправить пользователя на фактический URL-адрес загрузки.
1 голос
/ 14 февраля 2012

Если активна выходная буферизация, обработка файла с использованием PHP будет занимать много памяти, а производительность будет намного хуже, чем в случае обычных файлов, обслуживаемых apache.

Итак, чтобы добавить что-то к уже полученным ответам:

  • по завершении отправки заголовков завершите буферизацию вывода с помощью ob_end_flush(), чтобы содержимое файла не кэшировалось в памяти перед началом вывода
  • readfile() может передавать файл с диска в Интернет более эффективно, чем ваш цикл

Было сказано, но не может быть подчеркнуто достаточно: do включает заголовок Content-Length, так как это позволит загрузчику измерять прогресс.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...