Я пытаюсь написать сценарий, который создаст файл на сервере, а затем с помощью header() перенаправит пользователя к этому файлу. Затем примерно через 10 секунд я хочу удалить файл. Я пробовал это:
header('Location: '.$url);
flush();
sleep(10);
unlink($url);
Но браузер просто ждет завершения скрипта, а затем перенаправляется, но к тому времени файл уже удален. Есть ли способ сообщить браузеру «конец файла», а затем продолжить вычисления? Или, может быть, PHP запустит другой скрипт, но не дождется его завершения?






Вы можете попробовать сделать что-то вроде этого:
<iframe src = "<?=$url?>"></iframe>
....
<?
sleep(10);
unlink($url);
?>
Другой вариант - использовать curl - тогда вы загружаете файл в запрос и отображаете его пользователю.
Вопрос - вы хотите удалить файл, который не может быть у пользователя - я боюсь, что это невозможно, когда пользователь загружает файл, он временно находится в его браузере - чтобы он мог его сохранить.
Следующий вариант - если вы знаете тип этого файла, вы можете сгенерировать заголовок содержимого / типа, чтобы пользователь загрузил файл. А потом удаляешь.
Это просто идеи, не знаю, что подойдет вам (если есть :))
На данный момент я обнаружил, что единственный способ сделать это - указать длину содержимого в заголовке. Попробуйте добавить это:
header("Content-Length: 0");
перед вашим флешем ();
http://us2.php.net/ignore_user_abort
Будьте очень осторожны, используя это, вы можете довольно быстро убить сервер, злоупотребляя им.
Возможно, вам будет лучше, если страница PHP будет обслуживать файл. В этом случае нет необходимости создавать временный файл и удалять его, просто отправьте данные, которые вы намеревались записать, во временный файл. Вам нужно будет правильно установить заголовки, чтобы браузер мог определить тип отправляемого файла. то есть Content-Type: text / xml; для xml или image / jpeg для jpg.
Этот метод также обрабатывает медленные клиенты, которым требуется больше времени для загрузки файла.
В качестве альтернативы .... вместо того, чтобы возиться с динамической генерацией файлов на лету ... почему бы не сделать такой обработчик:
tempFile.php? key = {md5 hash}
tempFile.php затем запрашивает содержимое базы данных, memcache (с дополнительным ключом) или apc.
Вы идете неверным путем. Вы можете создать файл и передать его им, а также удалить его за один шаг.
<?php
$file_contents = 'these are the contents of your file';
$random_filename = md5(time()+rand(0,10000)).'.txt';
$public_directory = '/www';
$the_file = $public_directory.'/'.$random_filename;
file_put_contents($the_file, $file_contents);
echo file_get_contents($the_file);
unlink($the_file);
?>
Если вы сделаете это таким образом, файлы будут удалены сразу после того, как пользователь их увидит. Конечно, это означает, что файл вообще не должен существовать. Итак, вы можете сократить код до этого:
<?php
$file_contents = 'these are the contents of your file';
echo $file_contents;
?>
Все зависит от того, где вы берете контент, который хотите им показать. Если это из файла, попробуйте:
<?php
$file_contents = file_get_contents($filename_or_url);
echo $file_contents;
?>
Что касается автоматического удаления файлов, просто настройте задание cron, которое запускается каждые 10 секунд и удаляет все файлы в вашей временной папке, где filemtime ($ filename) превышает 5 минут секунд.
Если вы хотите реализовать свой оригинальный дизайн, прочтите этот вопрос о запуске команды в PHP, которая называется «выстрелил и забыл» Асинхронная оболочка exec в PHP
Как видно на \Symfony\Component\HttpFoundation\Response::send
/**
* Sends HTTP headers and content.
*
* @return Response
*
* @api
*/
public function send()
{
$this->sendHeaders();
$this->sendContent();
if (function_exists('fastcgi_finish_request')) {
fastcgi_finish_request();
} elseif ('cli' !== PHP_SAPI) {
// ob_get_level() never returns 0 on some Windows configurations, so if
// the level is the same two times in a row, the loop should be stopped.
$previous = null;
$obStatus = ob_get_status(1);
while (($level = ob_get_level()) > 0 && $level !== $previous) {
$previous = $level;
if ($obStatus[$level - 1]) {
if (version_compare(PHP_VERSION, '5.4', '>=')) {
if (isset($obStatus[$level - 1]['flags']) && ($obStatus[$level - 1]['flags'] & PHP_OUTPUT_HANDLER_REMOVABLE)) {
ob_end_flush();
}
} else {
if (isset($obStatus[$level - 1]['del']) && $obStatus[$level - 1]['del']) {
ob_end_flush();
}
}
}
}
flush();
}
return $this;
}
Да, создание страницы и последующее ее уничтожение - пустая трата ресурсов, просто распечатайте этот файл пользователю, убивает двух зайцев одним выстрелом. Если вы пытаетесь сделать что-то вроде вывода CSV, печать его в браузере по-прежнему остается лучшим способом.