Выборочное разрешение на загрузку файлов с Apache и PHP - PullRequest
3 голосов
/ 10 ноября 2010

У меня есть веб-сайт с возможностью загрузки файлов.Однако не всем разрешено загружать каждый файл.Например, если я вхожу в систему как администратор, я могу загружать все файлы, но если я вхожу как пользователь, я могу загружать только определенные файлы.

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

1:

echo file_get_contents($file);

2:

readfile($file);

3:

if (($handle = fopen($file, "rb")) !== false)
{
  while (!feof($handle))
  {
    echo fread($handle, 4096);
  }
  fclose($handle);
}

Я обнаружил, что все этиметоды очень ненадежны при тестировании файла размером 500 МБ.Первое и второе не работают со всеми браузерами и случайными процентами.Иногда они уже терпят неудачу после нескольких мегабайт, а иногда они достигают 80%.Но в итоге они просто перестанут скачивать без каких-либо ошибок.

Третий метод наиболее надежен.Он хорошо загружается в Firefox (хотя и слишком медленно; около 700 КБ / с, в то время как он от localhost и метод readfile работает со скоростью 25 МБ / с, когда он работает) и Chrome, но в Internet Explorer он в большинстве случаев дает сбой.В IE он сначала застревает при «получении информации о файле» без какого-либо диалога «Открыть / Сохранить».Когда я отменяю это и пытаюсь снова, я получаю диалоговое окно «Открыть / Сохранить».

Я искал в Интернете, и я не могу найти какой-либо удовлетворительный метод, который действительно работает хорошо.Предпочтительно, я просто хочу, чтобы Apache выполнял загрузку файлов, поскольку это всегда работает без проблем.Но я не хочу помещать все файлы в общедоступный каталог, поскольку каждый может загрузить все файлы.

Какие у меня варианты?Есть ли лучший метод?

Ответы [ 2 ]

2 голосов
/ 10 ноября 2010

1) и 2) сломаются для больших файлов, потому что они заполняют память скрипта содержимым файла. Ограничение памяти обычно составляет около 32 или 64 МБ, и не имеет смысла брать его выше.

Третий метод должен работать хорошо, потому что он не заполняет память скрипта; однако не забудьте отправить правильные заголовки content-type и content-length.

Существует альтернатива передаче файла через PHP, которую я сам не работал, но, кажется, работает хорошо, заголовок X-Sendfile .

0 голосов
/ 10 ноября 2010

Есть несколько опций, включая установку заголовков PHP, заставляющих скачивать:

header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="example.zip"'); 
header('Content-Transfer-Encoding: binary');

http://www.jonasjohn.de/snippets/php/headers.htm

Или вы можете добавить iFrame, связанный с данным файлом ... не очень элегантно.

Это также интересный урок:

http://w -shadow.com / блог / 2007/08/12 / как к силе-файлов скачать-с PHP /

...