在页面返回后继续运行PHP脚本

7

我正在尝试编写一个脚本,它将在服务器上创建一个文件,然后使用header()将用户重定向到该文件。然后,大约10秒钟后,我想删除该文件。我已经尝试过以下代码:

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

但是浏览器只会等待脚本完成,然后被重定向,但此时文件已被删除。有没有办法告诉浏览器“文件结束”,然后继续计算?或者让PHP启动另一个脚本,但不等待该脚本完成?

8个回答

4
您最好让PHP页面提供文件。在这种情况下,无需创建临时文件并删除它,只需发送您打算写入临时文件的数据即可。您需要正确设置标题,以便浏览器可以识别您正在发送的文件类型。例如,对于XML,Content-Type: text/xml;对于JPG,Content-Type: image/jpeg。
此方法还处理下载文件时间较长的慢速客户端。

是的,创建一个页面然后销毁它是浪费资源,只需将此文件打印给用户,一举两得。如果您想要输出CSV之类的内容,将其打印到浏览器仍然是最好的方式。 - TravisO

1

1
或者...不要在动态生成文件时搞乱了,为什么不像这样创建一个处理程序:
tempFile.php?key={md5哈希值}
然后,tempFile.php可以查询数据库、memcache(带有附加的前缀键)或apc来获取内容。

1

到目前为止,我发现唯一的方法是在头部提供内容长度。尝试添加以下内容:

header("Content-Length: 0");

在执行 flush() 之前;


0

0
你可以试着这样做:
<iframe src="<?=$url?>"></iframe>

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

另一个选项是使用curl-然后您在请求中加载文件并向用户显示。

问题-您是否想删除用户无法拥有的文件-恐怕这是不可能的,当用户加载文件时,它会暂时存在于他的浏览器中-因此他可以保存它。

下一个选项-如果您知道此文件的类型,则可以生成内容/类型标头,以便用户下载该文件。 然后你删除它。

这只是简单的想法,不知道哪个适合您(如果有的话:))


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

-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秒运行一次的cron作业,并删除临时文件夹中所有的文件,其中filemtime($filename)大于5分钟的秒数。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接