Я использую X-SendFile Apache Module для загрузки больших файлов с сервера. Загрузки работают хорошо. Однако, когда начинается загрузка, мне нужно вывести в браузер какой-то текст, например: "Спасибо за загрузку файла..."
Моя проблема заключается в том, что я не могу выполнять оба сценария. Я могу либо загрузить файл, а затем текст не выводится на экран. Или, я могу вывести текст на экран, но тогда сценарий загрузки не запустится.
Как выполнить обе задачи в одном 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();
Ограничение:
Мне нужно иметь возможность загружать файл eaisly через URL. Пример: www.mydomain.com/?fileID=asl523n53twteHLfga
. Другими словами, скрипт загрузки PHP находится внутри index.php
. Когда пользователь входит на сайт www.mydomain.com
, отображается целевая страница домена. Однако, когда передается дополнительная переменная $_GET
, скрипт PHP распознает это и должен отображать Спасибо за загрузку... вместо целевой страницы.
Обходной путь приветствуется. Важно следить за желаемым результатом, сохраняя вышеуказанное ограничение. Тыкн ты очень.
Как насчет добавления отдельной страницы загрузки, которая будет загружать файл (например, 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()
.
Существует обходное решение. Вы можете создать iframe, внутри которого загрузите файл. Подробнее см. В коде.
Спасибо за страницу: (например, www.mydomain.com/?fileID=asl523n53twteHLfga)
<p>Thank you!</p>
<?php
$fileID = $_REQUEST['fileID'];
// csrf code individual for visitor, so visitor can 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();
}
?>