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


How do I get a PHP function to continue after return?

我遇到了一个问题,我在页面加载时调用了一个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

正如你所看到的,当文件不存在时,这就停止了,但我希望这里的东西在后台继续。这可能吗?还是我需要一种不同的方法?就像一份裙带工作什么的?感谢您的帮助。

您可以尝试像resque这样的排队系统https://github.com/chrisboulton/php-resque

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

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

我会用AJAX来实现。如果找到了图像,就把它放在那里。

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

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

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

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

  1. 您放置了一个带有指向脚本的src属性的常规<img>标记。

  2. 如果你的脚本需要重新生成,你可以让浏览器重定向到一个正在处理的图像。

  3. 如果图像已经准备好,您可以重定向到创建的图像(您也可以在页面上进行AJAX轮询)

如何执行步骤2

通常,浏览器必须等待脚本结束后才能执行渲染或重定向;但FastCGI(PHP-FPM)对此有一个特殊的功能:CCD_ 3。它基本上没有记录,但它的使用很简单:

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这样的任务调度程序。

您可以使用"try"answers"finally"

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

我无法发表评论,因为我的声誉低于50,但我想注意一下mohammadhasan的回答。它似乎有效,但在尝试和最终阻止时都避免"返回"语句

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