5

可能重复:
PHP中的异步shell exec

我需要在后台运行一个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)的链接时,网页显示“正在加载”。当我同时点击其他链接时,它没有响应。

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

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

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

帮助将不胜感激。

4

4 回答 4

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.
}
于 2011-06-03T07:53:24.177 回答
2

您可以在显示的页面中调用该命令,但在末尾附加一个& :

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

这样,该过程在后台启动。

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

于 2011-06-03T07:44:31.237 回答
0

与普通的 shell 脚本一样,您可以使用 & 符号来后台处理进程:

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

请参阅PHP 中的异步 shell exec

于 2011-06-03T07:44:26.853 回答
0

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

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

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

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

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

于 2011-06-03T07:46:54.477 回答