0

I've got an application (usual .exe file) that I can run in console (e.g. as daemon). It works fine and Input/Output is just standard STDIN/STDOUT so from the console (windows or debian) there is no problem. But I need interact with that with php (my php script).

That's again no problem because there is a lot of 'stuff' in PHP to do that (proc_open, exec, system, pipes, strings etc etc etc). The problem's that the application must work during getting/receiving data (in simple words -that's a daemon) but all the functions above waiting for the end of execution of the command and after return result.

from php.net

Note: If a program is started with this function, in order for it to continue running in the
background, the output of the program must be redirected to a file or another output
stream. Failing to do so will cause PHP to hang until the execution of the program ends.

It's known how to redirect to another input/output (eg. to file) with > | & etc.:

$last_line = system("myfile.exe>file2.txt", $retval);

that works fine even as daemon. Although I can't get how to implement an input in the mode. However, my main problem how to redirect standard output to a non-file resource. On php.net is written:

Windows compatibility: Descriptors beyond 2 (stderr) are made available to the child process as inheritable handles, but since the Windows architecture does not associate file descriptor numbers with low-level handles, the child process does not (yet) have a means of accessing those handles. Stdin, stdout and stderr work as expected.

So it woud be easy just command>&3 but I can't define new (my own) handles for I/O.

So the question is How to implement/handle input/output (to BOTH ways) for a daemon!!!

I've scrutinized tons of sources in Internet but didn't get a normal answer for PHP. It's elementary for Java, for example, for C/C++ but not for PHP.

Maybe somebody help me - I would be very appreciate!

1 Answer 1

0

The proc_* functions are more powerful than you expect. Your assumption these functions will block is not correct.

After calling proc_open you can set every pipe to non-blocking. This will result in a way you can use fread without waiting for input from the process, and try to fwrite without waiting for the process to be able to accept it.

Also I would recommend to use socket_select to make sure you do not get into a tight loop trying to read/write to your executed process. A select construction will break it's sleep period when a file pointer (pipe in your case) is ready for reading or to be written to.

$descriptorspec = array(
  0 => array("pipe", "r"), // stdin
  1 => array("pipe", "w"), // stdout
  2 => array("file", "r") // stderr );

$process = proc_open('php', $descriptorspec, $pipes);

foreach($pipes as $pipe)
  stream_set_blocking($pipe, 0);

For more information see the documentation and comments of socket_select, stream_set_blocking, and proc_open.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.