返回后如何让PHP函数继续运行?

时间:2013-02-14 23:37:13

标签: php function recursion

我有一个问题,我在页面加载时调用PHP函数 - 该函数检查文件是否存在它返回文件名,如果它不存在它运行一个相当足智多谋并需要时间的脚本 - 转换来自音频文件的波形图像。问题是音频文件很大,因此创建文件可能需要一些时间,因此如果音频文件没有与之关联的此图像文件,则页面加载需要与进程一样长。

我所追求的是此函数返回占位符图像(如果不存在),但在页面加载后继续进行 - 或在后台。因此理论上,当以后重新加载页面时,正确的图像就会出现在那里。

我当前可以返回占位符图像,但随后进程停止并且图像不会生成。这是我到目前为止所做的:

function example($file_path, $file_name) {if ($file_path) {

if (file_exists("/path/to/folder/{$file_name}.png")) {
  return "/path/to/folder/{$file_name}.png";
}
if (!file_exists("/path/to/folder/{$audio_file_name}.png")) {

  return "/path/to/folder/processing.png";      

Some stuff in here

 return $new image

} return FALSE

正如您所看到的,当文件不存在时,这只会停止,但我希望此处的内容在后台继续。是可能还是我需要一种不同的方法?像一个cron工作或什么?任何帮助表示赞赏。

5 个答案:

答案 0 :(得分:3)

您可以尝试使用resque https://github.com/chrisboulton/php-resque

等排队系统

然后,您可以生成一个处理信息的作业,并使用“处理”图像快速返回。 使用这种方法,你不会知道它何时完成。

根据我的经验,这比操作人员与多线程支持编译php更容易。

答案 1 :(得分:2)

如果您在FastCGI / FPM上运行,可以考虑执行以下操作:

  1. 您将常规<img>标记的src属性指向您的脚本。

  2. 如果您的脚本需要重新生成,则会将浏览器重定向到处理图像。

  3. 如果图像准备就绪,您可以重定向到创建的图像(您也可以在页面上进行AJAX投票)

  4. 如何执行第2步?

    通常,浏览器必须等待脚本结束才能执行渲染或重定向;但FastCGI(PHP-FPM)具有以下特殊功能:fastcgi_finish_request。它基本上没有文档,但它的使用很简单:

    if ($need_to_process) {
        header('Location: /path/to/processing.png');
        fastcgi_finish_request();
        // do processing here
    } else {
        header('Location: /path/to/final_image.png');
    }
    

    <强>替代

    如果您有一个模板可以在执行fastcgi_finish_request()之前立即呈现,则可以将其应用于现有流程。

    另一种选择

    使用像Gearman这样的任务调度程序。

答案 2 :(得分:1)

我会用AJAX做的。如果找到图像,只需将其放在那里。

否则,放置占位符,并添加带有数据的JS标志以加载波形图像。

在生成HTML文档的PHP代码中,不会发生转换。而且你有另一个请求处理程序来处理来自JS的请求,它使用提供的数据进行转换。

最初在HTML文档生成代码上创建的数据将传递给JS,JS将使用它来发送转换请求。当JS等待响应时,你处理加载时间,当响应到来时,你把它放在占位符上。

答案 3 :(得分:0)

您可以使用“尝试”和“最终”

try {
    return "hello world";
} finally {
    //do something
}

答案 4 :(得分:0)

我无法发表评论,因为我的声誉在50岁以下,但是我想在穆罕默德哈桑的答案中提及一些内容。似乎可行,但在try和finally块中均避免使用“ return”语句

try {
    return "hello world";
} finally {
    //do not put return here
}

示例:

function runner() {
    try {
        return "I am the trial runner";
    } finally {
        return "I am the default runner";
    }
}

echo runner();

仅显示I am the default runner