2008-12-10 5 views
5

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

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

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

ответ

0

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

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

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

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

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

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

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

1

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

header("Content-Length: 0"); 

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

4

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

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

+0

Да, создание страницы и то уничтожение это пустая трата ресурсов, просто распечатайте этот файл пользователю, убив двух птиц одним камнем. Если вы пытаетесь сделать что-то вроде вывода CSV, печать его в браузере по-прежнему является лучшим способом. – TravisO 2008-12-10 22:57:42

1

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

tempFile.php ключ = {md5 хэш}

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

-1

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

<?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; 
?> 

Что касается удаления файлов автоматически, просто настроить работу хрон, которая проходит каждые 10 секунд, и удаляет все файлы в папке темп, что где filemtime ($ имя_файла) больше чем за 5 минут.

0

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

0

Как видно на \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; 
} 
Смежные вопросы