I want to execute java programs using php code. When i write the below code, the program written in the editor is getting compiled and executed successfully.
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
Note: $output
and $check
variables contains required input to compile & run
But, when I try to execute java programs where we need to input some data to contine with the execution, the above code doesn't works. For example, consider the JavaScannerExample
in the link: http://alvinalexander.com/java/edu/pj/pj010005
To execute the program in the link, I guess I need some interactive console to accept the input and continue with program execution. Please suggest me how to achieve this using php?
Update:
@Chris.. Tried proc_open
command as suggested. See my code below:
PHP Code
<?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 Code
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 Output
Enter your name: Enter your age:
Could you please check and let me know where did I went wrong?
Update2:
@Chris.. Thanks for your suggestion. It helped me get the output.
Here is the modified php code:
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;
}
This is the result I am getting.
Enter your name: Enter your age: Mark, your age is 32
There are multiple problems with this type of result. First I am trying to build an interactive console. So for the above example, the pipes need to work in parallel. However, I am not able to retrieve pipes[1] until I close pipes[0]. Because if I get the value of pipes[1] earlier in the code the program is hanging. In this scenario. First I need to be able to read the input which is "Enter your name:" Then enter input which is "Mark". Next steps are similar I need to get the text "Enter age:" and enter input "32". finally I need to get the final output which is "Mark, your age is 32" and detect the program is finished and then close both the pipes. Is this possible?
Use proc_open instead of exec. It can be used to retrieve a pipe to stdin
which can be used to provide input to your Java application. The first example on the proc_open
manual page demonstrates how to do this.