php system()shell_exec()挂起浏览器

时间:2011-06-03 07:36:00

标签: php shell-exec

  

可能重复:
  Asynchronous shell exec in PHP

我需要在后台运行一个java程序。

process.php包含

shell_exec("php php_cli.php")

php_cli.php包含

shell_exec("java -jar BiForce.jar settings.ini > log.txt");

我使用ajax

异步调用process.php

当我点击调用ajax函数的网页中的链接(用于运行process.php)时,webage显示“正在加载”。当我同时点击其他链接时它没有响应。

java程序大约需要24小时才能完成执行,因此用户不会等到执行结束。

问题是浏览器继续加载,并且在点击链接时不会转到其他页面。

我也尝试过使用system(),但同样的问题......

非常感谢帮助。

4 个答案:

答案 0 :(得分:5)

使用shell_exec等待命令挂起,这就是你的脚本正在做的事情。

如果您的命令没有任何等待时间,那么您的脚本也不会。

您可以从原始脚本调用另一个PHP脚本,而无需等待它挂断:

$processId = shell_exec(
    "nohup " .                          // Runs a command, ignoring hangup signals.
    "nice " .                           // "Adjusted niceness" :) Read nice --help
    "/usr/bin/php -c " .                // Path to your PHP executable.
    "/path/to/php.ini -f " .            // Path to your PHP config.
    "/var/www/php_cli.php " .           // Path to the script you want to execute.
    "action=generate > /process.log " . // Log file.
    "& echo $!"                         // Make sure it returns only the process id.
    );

然后可以使用此命令检测脚本是否已完成:

exec('ps ' . $processId, $processState);
// exec returns the result of the command - but we need to store the process state.
// The third param is a referenced variable.

// First key in $processState is that it's running.
// Second key would be that it has exited.
if (count($processState) < 2) {
    // Process has ended.
}

答案 1 :(得分:1)

您可以在显示的页面中调用该命令,但最后添加&amp;

shell_exec("java -jar BiForce.jar settings.ini > log.txt &");

这种方式在后台启动。

此外,没有必要(除非您的应用程序定义)创建一个process.php,它本身通过shell exec调用php。您可以通过include将相同的功能归档到另一个文件。

答案 2 :(得分:0)

与普通shell脚本一样,您可以使用&符号来处理该过程:

shell_exec("java -jar BiForce.jar settings.ini > log.txt &");

请参阅Asynchronous shell exec in PHP

答案 3 :(得分:0)

首先,您可能想重新设计这个概念。我不确定这些程序到底做了什么,但显然这可能会导致潜在的问题......

我建议你这样做,而不是通过PHP启动外部进程:

  • 您的ajax调用在某个临时目录中创建(或重用)文件(可能使用用户会话生成该文件)
    • 一些数据写入文件,请求结束
  • 你的罐子是单独发射的,并且无限期地运行
    • Java程序会定期扫描临时目录中的新文件,或者某个文件是否已被修改
    • 解析它,并执行24小时长的过程,或在必要时调整任何先前的执行

根据相同的想法,您甚至可以使用套接字来与该Java程序进行通信,或者以任何其他方式进行通信。

让Java程序一直运行而不是启动新进程的优点是能够在应用程序的生命周期内重用系统资源;例如,如果您的程序使用数据库连接,或任何数据,缓存等。