如何给 java 程序输入并使用 PHP 继续执行?
How to give input to java program and continue with execution using PHP?
我想使用 php 代码执行 java 程序。当我编写下面的代码时,在编辑器中编写的程序正在编译并成功执行。
putenv('path=C:\Program Files\Java\jdk1.8.0_73\bin');
echo shell_exec("javac $output 2>&1"); // for compiling and creating class file
echo exec("java $check 2>&1"); // for executing generated class file and prints output
注意:$output
和 $check
变量包含编译所需的输入 & 运行
但是,当我尝试执行需要输入一些数据以继续执行的 java 程序时,上面的代码不起作用。例如,考虑 link 中的 JavaScannerExample
:http://alvinalexander.com/java/edu/pj/pj010005
要执行 link 中的程序,我想我需要一些交互式控制台来接受输入并继续执行程序。请建议我如何使用 php?
实现此目的
更新:
@Chris.. 按照建议尝试了 proc_open
命令。请参阅下面的代码:
PHP代码
<?php
$JAVA_HOME = "C:\Java\jdk1.7.0_79";
$PATH = "$JAVA_HOME\bin";
putenv("JAVA_HOME=$JAVA_HOME");
putenv("PATH=$PATH");
$result = shell_exec("javac JavaScannerExample.java 2>&1");
if ($result == ""){
$options = ["bypass_shell" => true];
$proc=proc_open("java JavaScannerExample",
array(
array("pipe","r"),
array("pipe","w"),
array("pipe","w")
),
$pipes,NULL,NULL,$options);
if (is_resource($proc)) {
fwrite($pipes[0], 'Mark');
fwrite($pipes[0], 32);
fclose($pipes[0]);
echo stream_get_contents($pipes[1]);
fclose($pipes[1]);
}
}
else{
echo $result;
}
?>
Java代码
import java.util.Scanner;
public class JavaScannerExample
{
public static void main (String[] args)
{
// create a scanner so we can read the command-line input
Scanner scanner = new Scanner(System.in);
// prompt for the user's name
System.out.print("Enter your name: ");
// get their input as a String
String username = scanner.next();
// prompt for their age
System.out.print("Enter your age: ");
// get the age as an int
int age = scanner.nextInt();
System.out.println(String.format("%s, your age is %d", username, age));
}
}
PHP输出
Enter your name: Enter your age:
能否请您检查一下,让我知道我哪里出错了?
更新2:
@Chris..谢谢你的建议。它帮助我获得了输出。
这是修改后的 php 代码:
putenv('path=C:\Program Files\Java\jdk1.8.0_73\bin');
$result = shell_exec("javac JavaScannerExample.java 2>&1");
if ($result == ""){
$options = ["bypass_shell" => true];
$proc=proc_open("java JavaScannerExample",
array(
array("pipe","r"),
array("pipe","w"),
array("pipe","w")
),
$pipes,NULL,NULL,$options);
if (is_resource($proc)) {
fwrite($pipes[0], "Mark\n");
fwrite($pipes[0], "32\n");
fclose($pipes[0]);
echo stream_get_contents($pipes[1]);
fclose($pipes[1]);
}
}
else{
echo $result;
}
这是我得到的结果。
Enter your name: Enter your age: Mark, your age is 32
此类结果存在多个问题。首先,我正在尝试构建一个交互式控制台。所以对于上面的例子,管道需要并行工作。但是,在关闭管道 [0] 之前,我无法检索管道 [1]。因为如果我在代码的前面得到 pipes[1] 的值,程序就会挂起。在这种情况下。首先,我需要能够读取 "Enter your name:" 的输入,然后输入 "Mark" 的输入。接下来的步骤类似,我需要获取文本 "Enter age:" 并输入“32”。最后我需要获得最终输出 "Mark, your age is 32" 并检测程序是否已完成,然后关闭两个管道。这可能吗?
使用 proc_open 而不是 exec。它可用于检索到 stdin
的管道,该管道可用于为您的 Java 应用程序提供输入。 proc_open
手册页上的第一个示例演示了如何执行此操作。
关于您的更新,也许使用 fread
而不是 stream_get_contents
。 fread
应该只读取可用的内容,而 stream_get_contents
将阻塞,直到保证流中不再有可读数据为止。如果您想在程序终止之前获得 stdout
,请尝试这样的操作。
$line_limit = 1024;
echo fread($pipes[1], $line_limit);
fwrite($pipes[0], "Mark\n");
echo fread($pipes[1], $line_limit);
fwrite($pipes[0], "32\n");
echo fread($pipes[1], $line_limit);
fclose($pipes[0]);
fclose($pipes[1]);
唯一需要注意的是,如果您在 Java 程序完成输出之前尝试读取数据,那么您可能无法获得预期的所有输出(可能什么都没有)。如果您遇到这种情况,我会在写入和读取之间添加延迟(sleep
)。
如果您想要一个真正的交互式终端,那么您可能必须生成一个不断轮询 stdout
以获取更多数据的后台线程,但这可能最好在另一个问题中提出。
我想使用 php 代码执行 java 程序。当我编写下面的代码时,在编辑器中编写的程序正在编译并成功执行。
putenv('path=C:\Program Files\Java\jdk1.8.0_73\bin');
echo shell_exec("javac $output 2>&1"); // for compiling and creating class file
echo exec("java $check 2>&1"); // for executing generated class file and prints output
注意:$output
和 $check
变量包含编译所需的输入 & 运行
但是,当我尝试执行需要输入一些数据以继续执行的 java 程序时,上面的代码不起作用。例如,考虑 link 中的 JavaScannerExample
:http://alvinalexander.com/java/edu/pj/pj010005
要执行 link 中的程序,我想我需要一些交互式控制台来接受输入并继续执行程序。请建议我如何使用 php?
实现此目的更新:
@Chris.. 按照建议尝试了 proc_open
命令。请参阅下面的代码:
PHP代码
<?php
$JAVA_HOME = "C:\Java\jdk1.7.0_79";
$PATH = "$JAVA_HOME\bin";
putenv("JAVA_HOME=$JAVA_HOME");
putenv("PATH=$PATH");
$result = shell_exec("javac JavaScannerExample.java 2>&1");
if ($result == ""){
$options = ["bypass_shell" => true];
$proc=proc_open("java JavaScannerExample",
array(
array("pipe","r"),
array("pipe","w"),
array("pipe","w")
),
$pipes,NULL,NULL,$options);
if (is_resource($proc)) {
fwrite($pipes[0], 'Mark');
fwrite($pipes[0], 32);
fclose($pipes[0]);
echo stream_get_contents($pipes[1]);
fclose($pipes[1]);
}
}
else{
echo $result;
}
?>
Java代码
import java.util.Scanner;
public class JavaScannerExample
{
public static void main (String[] args)
{
// create a scanner so we can read the command-line input
Scanner scanner = new Scanner(System.in);
// prompt for the user's name
System.out.print("Enter your name: ");
// get their input as a String
String username = scanner.next();
// prompt for their age
System.out.print("Enter your age: ");
// get the age as an int
int age = scanner.nextInt();
System.out.println(String.format("%s, your age is %d", username, age));
}
}
PHP输出
Enter your name: Enter your age:
能否请您检查一下,让我知道我哪里出错了?
更新2:
@Chris..谢谢你的建议。它帮助我获得了输出。
这是修改后的 php 代码:
putenv('path=C:\Program Files\Java\jdk1.8.0_73\bin');
$result = shell_exec("javac JavaScannerExample.java 2>&1");
if ($result == ""){
$options = ["bypass_shell" => true];
$proc=proc_open("java JavaScannerExample",
array(
array("pipe","r"),
array("pipe","w"),
array("pipe","w")
),
$pipes,NULL,NULL,$options);
if (is_resource($proc)) {
fwrite($pipes[0], "Mark\n");
fwrite($pipes[0], "32\n");
fclose($pipes[0]);
echo stream_get_contents($pipes[1]);
fclose($pipes[1]);
}
}
else{
echo $result;
}
这是我得到的结果。
Enter your name: Enter your age: Mark, your age is 32
此类结果存在多个问题。首先,我正在尝试构建一个交互式控制台。所以对于上面的例子,管道需要并行工作。但是,在关闭管道 [0] 之前,我无法检索管道 [1]。因为如果我在代码的前面得到 pipes[1] 的值,程序就会挂起。在这种情况下。首先,我需要能够读取 "Enter your name:" 的输入,然后输入 "Mark" 的输入。接下来的步骤类似,我需要获取文本 "Enter age:" 并输入“32”。最后我需要获得最终输出 "Mark, your age is 32" 并检测程序是否已完成,然后关闭两个管道。这可能吗?
使用 proc_open 而不是 exec。它可用于检索到 stdin
的管道,该管道可用于为您的 Java 应用程序提供输入。 proc_open
手册页上的第一个示例演示了如何执行此操作。
关于您的更新,也许使用 fread
而不是 stream_get_contents
。 fread
应该只读取可用的内容,而 stream_get_contents
将阻塞,直到保证流中不再有可读数据为止。如果您想在程序终止之前获得 stdout
,请尝试这样的操作。
$line_limit = 1024;
echo fread($pipes[1], $line_limit);
fwrite($pipes[0], "Mark\n");
echo fread($pipes[1], $line_limit);
fwrite($pipes[0], "32\n");
echo fread($pipes[1], $line_limit);
fclose($pipes[0]);
fclose($pipes[1]);
唯一需要注意的是,如果您在 Java 程序完成输出之前尝试读取数据,那么您可能无法获得预期的所有输出(可能什么都没有)。如果您遇到这种情况,我会在写入和读取之间添加延迟(sleep
)。
如果您想要一个真正的交互式终端,那么您可能必须生成一个不断轮询 stdout
以获取更多数据的后台线程,但这可能最好在另一个问题中提出。