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

时间:2014-09-06 13:41:49

标签: php unix

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

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

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

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

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

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

简化要求的示例脚本

假设此示例并帮助我修改此脚本以实现结果。我有两个PHP脚本“thread.php和createfile.php”。名称为“thread.php”的文件将由客户端通过Web浏览器打开。该脚本需要执行脚本“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延迟?

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

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

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

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

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

的示例

希望能帮到你

答案 2 :(得分:0)

最后,我从以下帖子得到了一个有效的答案: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