Продолжить запуск PHP-скрипта после возврата страницы - PullRequest
5 голосов
/ 11 декабря 2008

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

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

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

Ответы [ 8 ]

4 голосов
/ 11 декабря 2008

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

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

1 голос
/ 11 декабря 2008

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

tempFile.php? Key = {хэш md5}

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

1 голос
/ 11 декабря 2008

http://us2.php.net/ignore_user_abort

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

1 голос
/ 11 декабря 2008

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

header("Content-Length: 0");

до вашего сброса ();

0 голосов
/ 11 сентября 2015

Как видно на \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 голосов
/ 24 февраля 2011

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

0 голосов
/ 11 декабря 2008

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

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

0 голосов
/ 11 декабря 2008

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

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

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

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...