Продолжайте запускать скрипт php после того, как страница будет возвращена

Я пытаюсь написать скрипт, который будет создавать файл на сервере, а затем использовать header()для перенаправления пользователя к этому файлу. Затем примерно через 10 секунд я хочу удалить файл. Я пробовал это:

header('Location: '.$url);
flush();
sleep(10);
unlink($url);

Но браузер просто ждет завершения сценария, затем перенаправляется, но к тому времени файл был удален. Есть ли какой-то способ сказать браузеру «конец файла», а затем продолжать вычисления? Или, может быть, PHP запустит другой скрипт, но не дождется его завершения?

6 php
10.12.2008 21:15:50
8 ОТВЕТОВ

Вы можете попробовать сделать что-то вроде этого:

<iframe src="<?=$url?>"></iframe>

....
<?
sleep(10);
unlink($url);
?>

Другой вариант - использовать curl - тогда вы загружаете файл в запрос и отображаете его пользователю.

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

Следующая опция - если вы знаете тип этого файла, вы можете сгенерировать заголовок содержимого / типа, чтобы пользователь скачал файл. А потом вы удалите его.

Это просто простые идеи, не знаю, что подойдет вам (если есть :))

0
10.12.2008 21:28:58

Пока я обнаружил, что единственный способ сделать это - указать длину содержимого в заголовке. Попробуйте добавить это:

header("Content-Length: 0");

до вашего флеша ();

1
10.12.2008 21:31:26

http://us2.php.net/ignore_user_abort

Будьте очень осторожны, используя это, вы можете довольно быстро убить сервер, злоупотребив им.

1
10.12.2008 22:02:56

Возможно, вам лучше иметь страницу PHP, которая обслуживает файл. В этом случае не нужно создавать временный файл и удалять его, просто отправьте данные, которые вы намеревались записать во временный файл. Вам нужно будет правильно установить заголовки, чтобы браузер мог определить тип файла, который вы отправляете. т.е. Content-Type: text / xml; для XML или изображения / JPEG для JPG.

Этот метод также обрабатывает медленные клиенты, которые загружают файл дольше.

4
10.12.2008 22:04:32
Да, создание страницы, а затем ее уничтожение - пустая трата ресурсов, просто распечатайте этот файл для пользователя, убив двух зайцев одним выстрелом. Если вы пытаетесь сделать что-то вроде вывода CSV, распечатать его в браузере по-прежнему лучше.
TravisO 10.12.2008 22:57:42

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

tempFile.php? key = {md5 hash}

Затем tempFile.php запрашивает содержимое в БД, memcache (с дополнительным префиксным ключом) или apc.

1
10.12.2008 22:05:34

Вы идете об этом неправильно. Вы можете создать файл и предоставить его им, а также удалить его за один шаг.

<?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 минут.

-1
11.12.2008 02:41:57

Если вы хотите реализовать свой оригинальный дизайн, прочитайте этот вопрос о запуске команды в PHP, которая называется «запустить и забыть». Асинхронная оболочка исполняется в PHP.

0
23.05.2017 11:52:13

Как видно на \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;
}
0
11.09.2015 09:27:21