繁体   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