2013-11-27 3 views
0

Я использую X-SendFile Apache Module для загрузки больших файлов с сервера. Загрузки работают хорошо. Однако, когда начинается загрузка, мне нужно вывести некоторый текст в браузер, например: «Спасибо, что загрузил файл ...»PHP, X-SendFile: отправка файла вместе с выводом текста в браузер (через echo)

Моя проблема заключается в том, что я не могу выполнять оба сценария. Я могу либо загрузить файл, а затем текст не выводится на экран. Или, я могу вывести текст на экран, но тогда сценарий загрузки не запустится.

Как выполнить обе задачи в одном скрипте php, пожалуйста, загрузите файл и отправьте текстовый контент в браузер/веб-страницу? Проблема, вероятно, возникает в заголовках выходных данных HTTP, но я не знаю, как ее решить.

этого образца кода я использую для загрузки файлов с помощью X-SendFile (работает правильно самостоятельно):

   header('Content-Description: File Transfer'); 
       header("Content-Disposition: attachment; filename=\"". basename($filePath) . "\""); 
       header('Content-Transfer-Encoding: binary'); 
       header('Expires: 0'); 
       header('Cache-Control: no-store, no-cache, must-revalidate'); 
       header('Pragma: no-cache'); 
       header('Content-Length: ' . filesize($filePath)); 
       header("X-Sendfile: $filePath"); 

Для завершения, это мой тест echo"" строка. Если он помещен над кодом X-Sendfile, он выводится, но загрузка не запускается. Если ставится под кодом X-SendFile, файл получает загружены, но nothign вторит в браузере:

echo "SUCCESS!!!"; 
ob_flush(); 

Constraint:

Мне нужно, чтобы иметь возможность загрузить файл eaisly через URL. Пример: www.mydomain.com/?fileID=asl523n53twteHLfga. Другими словами, сценарий загрузки PHP находится в пределах index.php. Когда пользователь вводит www.mydomain.com, отображается целевая страница домена. Однако, когда передается дополнительная переменная $_GET, скрипт PHP распознает это и должен отображать Спасибо за скачивание ... вместо целевой страницы.

Обходное решение приветствуется. Важно следить за желаемым результатом, сохраняя вышеуказанное ограничение. Тыкн ты очень.

+2

Невозможно. Большинство сторонних браузеров не поддерживается (или поддерживается хорошо). ответ обычно состоит из ОДНОГО потока данных. большинство людей обходятся, выбирая промежуточную страницу с благодарностью, а затем мета-обновление, указывающее на фактическую ссылку для скачивания. –

+0

Марк Б, спасибо за ваш ответ. Я понимаю, что вы имеете в виду. Это готовое решение. Я буду ждать, чтобы собрать еще несколько ответов, и если ничего лучше не придет, я пойду в направлении, которое вы указали. Спасибо и +1. –

ответ

2

Как насчет добавления отдельной загрузки страницы, которая будет скачать файл (т.е. download.php?fileID=XYZ) и с вашей страницы индекса показывают сообщение следующим образом:

<?php 

function homeScreen() { 
    // your home content 
} 

function downloadFileScreen ($id) { 
?> 
<h2>Thank you for your download!</h2> 
Your download should start automatically, if it does not, click 
<a href="download.php?fileID=<?php print $id; ?>">here</a> 
<script type="text/javascript"> 
window.setTimeout('location.href="download.php?fileID=<?php print $id; ?>"',3000); 
</script> 
<?php 
} 

if (isset($_GET['fileID'])) { 
    $id= $_GET['fileID']; 
    downloadFileScreen ($id); 
?> 
} else { 
    // no ID passed, show home screen 
    homeScreen(); 
} 
?> 

Я не слышал о какой-либо поддержки браузера смешивания как скачать и отображение содержимого HTTP в одном запросе, но я посмотрю, можно ли это сделать, используя ob_start() и ob_flush().

+1

Привет, Sascha, я внедрил ваше решение (так работает только для меня), и он работает хорошо. Позвольте поблагодарить вас за ваш ответ и отметить его как принятый ответ. Благодарю. –

+0

Большое спасибо, рад, что это может помочь вам начать работу! – SaschaM78

2

Существует обходное решение. Вы можете создать iframe, внутри которого загрузите файл. Подробнее см. В коде.

Спасибо страницы (например www.mydomain.com/?fileID=asl523n53twteHLfga)

<p>Thank you!</p> 
<?php 
$fileID = $_REQUEST['fileID']; 
// csrf code individual for visitor, so visitor can's send direct link to friend 
$csrf = md5(uniqid(rand(), true)); 
$_SESSION['csrf'] = $csrf; 
// with iframe file will be downloaded 'in background' 
echo '<iframe src="downloadFile.php?fileID=' . urlencode($fileID) . '&csrf=' . urlencode($csrf) . '" width="0" height="0"></iframe>'; 
?> 

downloadFile.php (например www.mydomain.com/downloadFile.php?fileID=asl523n53twteHLfga)

<?php 
$fileID = $_REQUEST['fileID']; 
if ($_REQUEST['csrf'] == $_SESSION['csrf']) 
{ 
    // download file 
    header('Content-Description: File Transfer'); 
    header("Content-Disposition: attachment; filename=\"". basename($filePath) . "\""); 
    header('Content-Transfer-Encoding: binary'); 
    header('Expires: 0'); 
    header('Cache-Control: no-store, no-cache, must-revalidate'); 
    header('Pragma: no-cache'); 
    header('Content-Length: ' . filesize($filePath)); 
    header("X-Sendfile: $filePath"); 
    die(); 
} 
else 
{ 
    // csrf from request not equal csrf saved in session, so probably this is direct link to file received from other user 
    // redirect to 'thank you' page 
    header('Location: /?fileID=' . urlencode($fileID)); 
    die(); 
} 
?> 
+1

Привет и спасибо за ваш ответ. Ваш ответ содержит отличный пример, я считаю, что он будет работать jus perferctly. Еще один замечательный пример - решение выше от Саши. Я попробовал решение Саши, и это сработало хорошо для меня. Поскольку я должен принять решение, какое решение я буду отмечать как принятый ответ, я решим для Саши, так как его ответ я действительно выполнил. Я дам вам +1 за отличный совет. Спасибо. –