如何在unix服务器上后台运行PHP代码


How To Run PHP Code In The Background on unix server

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

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

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

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

我将在后台处理数据,并在处理完成后向客户端发送邮件。Cron选项卡在这里不可行,因为客户每月可能只使用这些功能几次,而且时间范围出乎意料。

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

简化需求的示例脚本

假设这个例子并帮助我修改这个脚本以获得结果。我有两个PHP脚本"thread.PHP和createfile.PHP"。客户端将通过web浏览器打开名为"threadphp"的文件。这个脚本需要执行脚本"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延迟?

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

使用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'); 
?> 

如果您在窗口中:

<?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部分:如何在后台使用EXEC()和CMD 执行PHP脚本

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

如果你的提要每个都有超过30000条记录,那么PHP FPM就会出现超时问题。因此,您的脚本必须使用PHP CLI运行(请检查服务器参数中的PHP CLI超时)。

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

希望这将帮助您

最后我从下面的帖子中得到了一个有效的答案:php exec命令(或类似命令)不等待结果

因此,我按照如下方式编辑代码,以使我的需求发挥作用。但我不知道它是如何工作的。我只是复制了这个答案的语法,并在这里进行了修改。

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