简体   繁体   English

返回页面后继续运行php脚本

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

I'm trying to write a script that will create a file on the server then use header() to redirect the user to that file. 我正在尝试编写一个脚本,它将在服务器上创建一个文件,然后使用header()将用户重定向到该文件。 Then, after about 10 seconds I want to delete the file. 然后,大约10秒后我想删除该文件。 I've tried this: 我试过这个:

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

But the browser just waits for the script to complete then gets redirected, but the file hes been deleted by that time. 但是浏览器只是等待脚本完成然后被重定向,但是那个文件被删除了。 Is there someway to tell the browser "end of file", then keep computing? 有没有办法告诉浏览器“文件结束”,然后继续计算? Or maybe have PHP start another script, but not wait for that script to finish? 或者可能让PHP启动另一个脚本,但不等待该脚本完成?

You might be better off having the PHP page serve the file. 你可能最好让PHP页面提供文件。 No need to create a temporary file in this case and delete it, just send out the data you intended to write to the temporary file. 在这种情况下无需创建临时文件并将其删除,只需将要写入的数据发送到临时文件即可。 You will need to set the headers correctly so the browser can identify the type of file you are sending. 您需要正确设置标头,以便浏览器可以识别您要发送的文件类型。 ie Content-Type: text/xml; 即Content-Type:text / xml; for xml or image/jpeg for jpg's. 对于jpg的xml或image / jpeg。

This method also handles slow clients that take longer to download the file. 此方法还处理下载文件需要更长时间的慢客户端。

The only way I've discovered to do this so far is to provide the content length in the header. 到目前为止,我发现这样做的唯一方法是在标题中提供内容长度。 Try adding this: 尝试添加此:

header("Content-Length: 0");

before your flush(); 在你的冲洗之前();

http://us2.php.net/ignore_user_abort http://us2.php.net/ignore_user_abort

Be very careful using this, you can pretty quickly kill a server by abusing it. 使用它时要非常小心,你可以通过滥用来快速杀死服务器。

Alternatively.... instead of messing with dynamically generating files on the fly... why not make a handler like so: 或者....而不是动态生成动态生成文件...为什么不像这样制作一个处理程序:

tempFile.php?key={md5 hash} tempFile.php?key = {md5 hash}

tempFile.php then either queries a DB, memcache ( with additional prepended key ), or apc for the content. 然后tempFile.php查询DB,memcache(带有附加的前置键)或apc作为内容。

As seen at \\Symfony\\Component\\HttpFoundation\\Response::send \\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;
}

You can try doing smth like that: 你可以尝试做那样的smth:

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

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

Other option is to use curl - then you load file in request and display to the user. 其他选项是使用curl - 然后在请求中加载文件并显示给用户。

Question - do you want to delete the file that user cannot have it - I'm afraid it's impossible, when user loads file it is temporaly in his browser - so he can save it. 问题 - 你想要删除用户无法拥有它的文件 - 我担心这是不可能的,当用户加载文件时,它是临时的浏览器 - 所以他可以保存它。

Next option - if you know type of this file, you can generate content/type header so user will download the file. 下一个选项 - 如果您知道此文件的类型,则可以生成内容/类型标题,以便用户下载该文件。 And then you delete it. 然后你删除它。

It's just simple ideas, don't know which will work for you( if any:) ) 这只是简单的想法,不知道哪个适合你(如果有的话):)

如果你想实现你的原始设计,请阅读关于在PHP中运行命令的问题,这是“火与不见” PHP中的异步shell exec

You're going about this the wrong way. 你这是错误的方式。 You can create the file and serve it to them, and delete it in one step. 您可以创建文件并将其提供给它们,然后一步删除它。

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

If you do it that way, the files get deleted immediately after the user sees them. 如果您这样做,文件会在用户看到后立即删除。 Of course, this means that the file need not exist in the first place. 当然,这意味着文件首先不需要存在。 So you could shorten the code to this: 所以你可以将代码缩短到这个:

<?php
$file_contents = 'these are the contents of your file';
echo $file_contents;
?>

It all depends on where you're getting the content you want to show them. 这一切都取决于您获取要显示的内容的位置。 If it's from a file, try: 如果它来自文件,请尝试:

<?php
$file_contents = file_get_contents($filename_or_url);
echo $file_contents;
?>

As for deleting files automatically, just setup a cron job that runs every 10 seconds, and deletes all the files in your temp folder that where filemtime($filename) is greater than 5 minutes' worth of seconds. 至于自动删除文件,只需设置一个每10秒运行一次的cron作业,并删除temp文件夹中filemtime($ filename)大于5分钟秒的所有文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM