【问题标题】:How To Run PHP Code In The Background on unix server如何在 unix 服务器的后台运行 PHP 代码
【发布时间】:2026-02-19 11:05:01
【问题描述】:

在我的网站中,我有一些功能可以上传用户的数据馈送。这些数据馈送通常有超过 30,000 条记录。并且每条记录都需要经过复杂的验证过程。因此,简单地说,此提要处理将需要 1 个多小时才能完成任务。这个长期运行的过程是不可避免的。

此提要由公共用户上传。并且提要大小小于 5MB 的文本文件。因此,我们不想授予 FTP 访问权限,也不想授予这些用户命令行访问权限。只有我们更愿意提供网络访问权限以上传提要。我们必须在上传后立即处理提要。一旦处理完毕,我们还必须向他们发送邮件报告。

现在的问题是长时间运行的网页在许多网络上引发了一些代理超时问题(因为需要 1 小时才能响应)。这是大多数客户端网络配置的问题。

我需要一种方法来在提要上传后触发 PHP 脚本。并且该脚本应该在后台运行,同时正确完成页面加载,而不会延迟客户端。

我会在后台处理数据并在处理完成后向客户端发送邮件。 Cron 选项卡在这里不可行,因为客户可能每月仅在意外的时间范围内使用这些功能几次。

如果有任何方法可以在后台触发 PHP 脚本但通过网络访问,请告诉我。

简化需求的示例脚本

假设这个例子并帮助我修改这个脚本以达到结果。我有两个 PHP 脚本“thread.php 和 createfile.php”。名为“thread.php”的文件将由客户端通过网络浏览器打开。该脚本需要执行脚本“createfile.php”。但需要 20 秒才能做出响应。但我们想让它在后台运行。并立即在浏览器中显示输出。

以下是示例脚本中的代码。

createfile.php (http://sugunan.net/demo/createfile.php)

<?php
sleep(20);
@unlink("phpfile.txt");
$myfile = fopen("phpfile.txt", "w") or die("Unable to open file!");
$txt = date("h:i:s")."\n";
fwrite($myfile, $txt);
fclose($myfile);
mail("someone@example.com","Background process","Process completed");
?>

创建的文件在网址可见:http://sugunan.net/demo/phpfile.txt

thread.php (http://sugunan.net/demo/thread.php)

<pre>
<?php
echo "Script start at: " . date('h:i:s') . "\n";
include("createfile.php"); //give a method to execute this script but in background without delay
echo "Script end at: " . date('h:i:s');
?>

这将给出sleep() 函数延迟的后续输出。

脚本开始于:02:53:27

脚本结束于:02:53:47

有没有办法在没有include() 方法的情况下执行“createfile.php”。并避免在后台处理“createfile.php”时出现 20 秒 sleep 延迟?

请考虑我想避免客户端的等待时间,并希望立即在浏览器上输出。

【问题讨论】:

  • 感谢您的 cmets 和回答。我已经放置了带有可访问网址的示例代码。您能否建议我如何修改这些脚本以避免延迟但在后台处理。
  • @Marcin Orlowski:我已经尝试过类似问题的并行处理建议。它可以很好地进行并行处理。但这又在等待浏览器中的输出。如果该延迟发生在浏览器上,那么客户端将再次遇到代理超时问题。以下示例是我尝试过的示例。 mullie.eu/parallel-processing-multi-tasking-php
  • @Marcin Orlowski:我从另一个堆栈溢出答案中找到了可行的解决方案:*.com/questions/3819398/…。相关问题和选择的答案符合我的要求。如果您愿意,可以将我的问题作为该问题的重复。

标签: php unix


【解决方案1】:

使用 exec()

http://php.net/manual/en/function.exec.php

这将允许您在另一个线程中运行长进程。我已经将它用于所有其他 PHP、Python 或 C 应用程序来将 wav 转换为 mp3、视频转换或通过大型 XML 文件进行解析......

确保在完成时通知您或用户(可能通过电子邮件),以及是否成功。

用 purehuman.info/demo 上的工作代码编辑...它现在实际上写入了文件。 这就是我要让 thread.php 看起来的样子:

<?php 
    echo "Script start at: " . date('h:i:s') . "\n"; 
    exec("php -f  createfile.php /dev/null &"); 
    echo "Script end at: " . date('h:i:s'); 
?> 

如果您在 Windows 中:

<?php 
    echo "Script start at: " . date('h:i:s') . "\n"; 
    exec("start /B php createfile.php"); //obviously change the paths etc where needed..
    echo "Script end at: " . date('h:i:s'); 
?> 

需要感谢 windows 部分:How to execue PHP scripts in the background using EXEC() and CMD

【讨论】:

  • 我把你最后编辑的代码放在这里:sugunan.net/demo/thread1.php 仍然有延迟。点击看看需要多长时间。
  • 但是您确实看到代码在我的网站上运行,对吧?您可以看到文件正在更新,并且需要 0 秒?
  • 哦,等等,你在 Windows 中吗?如果是这样, > /dev/null & 将不起作用。您可以将其替换为: exec("start /B php createfile.php");
  • 我正在使用 godaddy linux 主机。谢谢你帮助我。但是我如何从以下帖子中得到答案:*.com/questions/3819398/… 这是相同的问题和有效的解决方案。
  • 我最初输入了 nohup 代码,但不需要它。您介意从中删除 -1 吗?我的意思是,它有效:-)
【解决方案2】:

PHP 不是为这种工作而设计的。但是有一些技巧可以尝试这样做。

如果您的提要每个都有超过 30,000 条记录,那么您将遇到 PHP FPM 超时问题。因此,您的脚本必须使用 PHP CLI 运行(检查您的服务器参数以了解 PHP CLI 超时)。

您应该查看Rabbit MQ 并每分钟为队列中的consume 消息编写一个cron 作业。这里有一个 PHP 的例子 http://www.rabbitmq.com/tutorials/tutorial-two-php.html

希望对你有帮助

【讨论】:

  • CLI 很好。但是,如果它是每月一次的几次活动,则没有理由每分钟运行一次 cron。我们需要在客户端完成上传后立即处理这个脚本。
【解决方案3】:

最后我从以下帖子中得到了一个有效的答案:php exec command (or similar) to not wait for result

所以我按如下方式编辑代码来满足我的要求。但我不知道它是如何工作的解释。我只复制该答案的语法并在此处进行修改。

<?php 
echo "Script start at: " . date('h:i:s') . "\n"; 
exec('bash -c "exec nohup php createfile.php > /dev/null 2>&1 &"');
echo "Script end at: " . date('h:i:s'); 
?>

这里的php createfile.php 将是执行 PHP 脚本并继续而不等待输出的命令。

感谢Cristian

【讨论】: