簡體   English   中英

返回頁面后繼續運行php腳本

[英]Continue running a php script after page is returned

我正在嘗試編寫一個腳本,它將在服務器上創建一個文件,然后使用header()將用戶重定向到該文件。 然后,大約10秒后我想刪除該文件。 我試過這個:

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

但是瀏覽器只是等待腳本完成然后被重定向,但是那個文件被刪除了。 有沒有辦法告訴瀏覽器“文件結束”,然后繼續計算? 或者可能讓PHP啟動另一個腳本,但不等待該腳本完成?

你可能最好讓PHP頁面提供文件。 在這種情況下無需創建臨時文件並將其刪除,只需將要寫入的數據發送到臨時文件即可。 您需要正確設置標頭,以便瀏覽器可以識別您要發送的文件類型。 即Content-Type:text / xml; 對於jpg的xml或image / jpeg。

此方法還處理下載文件需要更長時間的慢客戶端。

到目前為止,我發現這樣做的唯一方法是在標題中提供內容長度。 嘗試添加此:

header("Content-Length: 0");

在你的沖洗之前();

http://us2.php.net/ignore_user_abort

使用它時要非常小心,你可以通過濫用來快速殺死服務器。

或者....而不是動態生成動態生成文件...為什么不像這樣制作一個處理程序:

tempFile.php?key = {md5 hash}

然后tempFile.php查詢DB,memcache(帶有附加的前置鍵)或apc作為內容。

\\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;
}

你可以嘗試做那樣的smth:

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

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

其他選項是使用curl - 然后在請求中加載文件並顯示給用戶。

問題 - 你想要刪除用戶無法擁有它的文件 - 我擔心這是不可能的,當用戶加載文件時,它是臨時的瀏覽器 - 所以他可以保存它。

下一個選項 - 如果您知道此文件的類型,則可以生成內容/類型標題,以便用戶下載該文件。 然后你刪除它。

這只是簡單的想法,不知道哪個適合你(如果有的話):)

如果你想實現你的原始設計,請閱讀關於在PHP中運行命令的問題,這是“火與不見” PHP中的異步shell exec

你這是錯誤的方式。 您可以創建文件並將其提供給它們,然后一步刪除它。

<?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秒運行一次的cron作業,並刪除temp文件夾中filemtime($ filename)大於5分鍾秒的所有文件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM