Jump to content
  • 0

как отдать файл пользователю ?


ask
 Share

Question

На сайте есть каталог files для хранения файлов, имена файлов храняться в бд.

Сейчас отдаю пользователям файлы вот таким образом:

while($block = mysql_fetch_object($res)) {
echo "<p><a href='./files/". $block->filename . "'>Скачать</a></p>";
}

При этом файл открывается в окне браузера, как в цикле сформировать ссылки(кнопки) при нажатии на которые

файлы отдавились пользователю с предложением сохранить ? а не открывались в браузере!

Link to comment
Share on other sites

13 answers to this question

Recommended Posts

  • 0

От заголовков зависит.

http://ru2.php.net/header

<?php
// We'll be outputting a PDF
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');
?>

Можно кинуть в папку files .htaccess перебивающий файлам Content-type на тот который браузеры сохраняют.

Сам не пробовал :)

Edited by Jenek
Link to comment
Share on other sites

  • 0

ВООО!

У меня похожий трабл возник.


$File = 'music.mp3';
if (file_exists($File))
{
header( 'Content-Description: File Transfer' );
header( 'Content-Type: audio/mpeg' );
header( 'Content-Disposition: attachment; filename=Музыка.mp3' );
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($File) );
ob_clean();
flush();

set_time_limit( 1200 );
readfile($File);
}

На сервере файл хранится с названием music.mp3, но пользователю я хочу передать его с названием Музыка.mp3

Для того и скрипт создавался.

А ещё для того, чтобы потом в БД увеличить счётчик скачиваний ;-)

НО! Файлы большие, мегабайтов по 9-10. И те, у кого медленное соединение с интернетом, могут скачать его только на 30-40%, потом закачка останавливается с ошибкой. set_time_limit( 1200 ) почему-то не помогает... И докачка, ясное дело, не поддерживается.

Есть ли какой-нибудь другой способ передать файл пользователю через скрипт, в не напрямую дав ссылку на файл???

Edited by mishaga
Link to comment
Share on other sites

  • 0

Вообще это плохая идея отдавать файл таким образом через PHP. Nginx имеет достаточно хорошие возможности — стоит попробовать поиграться с его настройками. Мне кажется, что можно запустить скрипт, который запишет всё, что нужно в БД и отдать нужный файл с нужным названием. Кстати, вроде тот же nginx поддерживает докачку, но не уверен. Это первое. Второе — это то, что я бы вообще не рекомендовал называть файл русскими буквами — это моветон. Ну а третье — мне кажется совершенно нелепым, когда уже есть файл с одним названием, а отдаётся с другим. Такое способ отдачи я считаю разумным использовать для формирования динамических отчётов в какой-нибудь .xls или для прочих подобных вещей, когда файла нет и он просто формируется динамически.

Link to comment
Share on other sites

  • 0

Окей, я понял. Но у меня нет своего web-сервера, я его арендую, там стоит apache.

Теперь задача стоит немного в другом.

Я хочу отдать пользователю именно mp3-файл

Если давать прямые ссылки на mp3-файлы, некоторые браузеры (Хром и IE) вместо того, чтобы скачивать, начинают его проигрывать своим встроенным проигрывателем! Это ужасно! Особенно, если пользователь "не шарит", он не сможет скачать файло. А на сайте ссылки на скачивание песни, а не на плеер. И те, кто нажимает на эти ссылки, они хотят именно сохранить файл, а не открыть в проигрывателе.

Поэтому надо использовать код

$File = 'music.mp3';
if (file_exists($File))
{
header( 'Content-Description: File Transfer' );
header( 'Content-Type: audio/mpeg' );
header( 'Content-Disposition: attachment; filename=music.mp3' );
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($File) );
ob_clean();
flush();

set_time_limit( 1200 );
readfile($File);
}

И пофик, если файл называется на английском, главное, чтобы его могли скачать.

Подскажите, как сделать, чтобы во время скачивания у пользователя не обрывалась докачка на 30%

set_time_limit( 1200 ); в этом не помог... =(

Или есть какой-то более нормальный способ дать людям скачать музыку?

Link to comment
Share on other sites

  • 0

Попробуйте файл запрашивать через скрипт так.

На входе подается файл(полный путь+имя). exit() нужен для того, чтобы в содержимое файла не попал контент выводимый остальной частью скрипта.

function download_file($filename)
{
header("Pragma: public");
header("Expires: 0");
header("Pragma: no-cache");
header("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0");
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header('Content-disposition: attachment; filename=' . basename($filename));
header("Content-Type: text/csv");
header("Content-Transfer-Encoding: binary");
header('Content-Length: ' . filesize($filename));
@readfile($filename);
exit(0);
}

Link to comment
Share on other sites

  • 0

<ссылка> (для сохранения нажмите на ссылке правой кнопкой мыши и выберите "save target as...")

В одном броузере будет "save target as...", в другом "Сохранить объект как..."

Не все посетители понимают что это одно и то же.

Link to comment
Share on other sites

  • 0

Попробуйте файл запрашивать через скрипт так.

На входе подается файл(полный путь+имя). exit() нужен для того, чтобы в содержимое файла не попал контент выводимый остальной частью скрипта.

function download_file($filename)
{
header("Pragma: public");
header("Expires: 0");
header("Pragma: no-cache");
header("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0");
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header('Content-disposition: attachment; filename=' . basename($filename));
header("Content-Type: text/csv");
header("Content-Transfer-Encoding: binary");
header('Content-Length: ' . filesize($filename));
@readfile($filename);
exit(0);
}

а это зачем? что оно даст?

header("Content-Type: text/csv");

и ещё такой вопрос... чем этот скрипт отличается от моего?

разве этот отдаст файл полностью? не зависнет на середине?

Link to comment
Share on other sites

  • 0

и ещё такой вопрос... чем этот скрипт отличается от моего?

разве этот отдаст файл полностью? не зависнет на середине?

ха, тут мысля проскочила, мож поэтому и не отдаёт у вас фаил целиком ? ограничение на использование оперативы?

Link to comment
Share on other sites

  • 0

А может есть какой-нибудь способ через .htaccess для mp3-файлов передавать свои заголовки?

Как-нибудь так:

<Files *.mp3>

***

</Files>

можно, но должен быть установлен модуль апача mod_headers.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. See more about our Guidelines and Privacy Policy