0

I have a PHP class that must launch a Java main as a separate process.
The execution must be synchronous and after its end I must read the stderr to handle and log potential errors.

I see that the most popular techniques to run separate processes from PHP are exec() and proc_open(). However, I do not understand which I should use and how.

Exec(), being synchronous and very easy to use, should be the best choice for me. However, from what I see here on StackOverflow: PHP StdErr after Exec(), it seems that the only way to get the stderr is to explicitly create a file for it. It does not seem to me like an elegant solution.

On turn, proc_open seems a really powerful tool, and it does allow direct, separate access to stdin, stdout and stderr. For what I need to do, the code should be something like this:

$proc = proc_open($cmd,[2 => ['pipe','w']],$pipes);
$stderr = stream_get_contents($pipes[2]);
fclose($pipes[2]);
proc_close($proc);
$error = var_dump($stderr)

The problem is proc_open is asynchronous, so if I get it right, I can not be sure that when I run stream_get_contents I will get any relevant message (errors might occur later!).

What should I do?

Andrea Rossi
  • 981
  • 1
  • 10
  • 23
  • 2
    `stream_get_contents()` will wait for EOF on the pipe, which will happen when the program ends. So that makes it synchronous. – Barmar Oct 06 '17 at 21:45
  • That's essentially what happens inside `exec()`, except it's doing it with stdout rather than stderr. – Barmar Oct 06 '17 at 21:45
  • You can't have an assignment after `return`, since `return` exits from the function. – Barmar Oct 06 '17 at 21:46
  • Did you look at the second answer in the question you linked to? It shows how to get `stderr` using `exec()` with output redirection in the command line. – Barmar Oct 06 '17 at 21:47
  • Hi Barmar, thanks for your great advices. I thought that `stream_get_contents()` would just take a snapshot of the `stderr` stream (I also read the documentation but it does not mention EOF; I guess PHP docs are quite... concise). This definitely solves my issue! if you write an answer with it, I can mark it as the solution for my problem. As for the answer in the exec question, I did read it, but creating a new file with `posix_mkfifo()` just for redirecting stderr whenever I call a process seems a bit meh, doesn't it? I would avoid that unless it is absolutely necessary :) – Andrea Rossi Oct 07 '17 at 08:47
  • 1
    The documentation says it reads the *remainder of a stream*. The remainder is everything until the stream ends, which is EOF. – Barmar Oct 07 '17 at 08:50
  • (As for the `return`, yeah, that's a copy-paste error ahah) – Andrea Rossi Oct 07 '17 at 08:50
  • Why do I need to write an answer when your code will work as written? – Barmar Oct 07 '17 at 08:51
  • You don't need to create a new file with `mkfifo`. Use the solution with `command 2>&1 >/dev/null` – Barmar Oct 07 '17 at 08:52
  • You only need the FIFO if you want to be able to get both stdout and stderr separately. – Barmar Oct 07 '17 at 08:52

0 Answers0