0

My PHP web app receives data from a stream. Once the page is loaded I need to open an .exe file using system() or exec() and after short period of time new data will come, so I must type specific command to this .exe to get its returned value, how can I do this?

I'm only able to do this manually in command prompt

path/to/.exe :: hit 'Enter'
command1 params1
//...
Rizier123
  • 58,877
  • 16
  • 101
  • 156
  • look for opening a process and pipes. Those are called standard input and standard output. IIRC this is [`proc_open`](http://de.php.net/proc_open) in PHP. (Process open.) Some example code is in a related question: http://stackoverflow.com/questions/10880589/multiple-input-with-proc-open – hakre Aug 12 '12 at 09:22

2 Answers2

1

What you're looking for is proc_open(). http://php.net/manual/en/function.proc-open.php

This will allow you to work with STDIO streams to communicate with the separate process.

Example from the PHP documentation:

$descriptorspec = array(
   0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
   1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
   2 => array("file", "/tmp/error-output.txt", "a") // stderr is a file to write to
);

$cwd = '/tmp';
$env = array('some_option' => 'aeiou');

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

if (is_resource($process)) {
    // $pipes now looks like this:
    // 0 => writeable handle connected to child stdin
    // 1 => readable handle connected to child stdout
    // Any error output will be appended to /tmp/error-output.txt

    fwrite($pipes[0], '<?php print_r($_ENV); ?>');
    fclose($pipes[0]);

    echo stream_get_contents($pipes[1]);
    fclose($pipes[1]);

    // It is important that you close any pipes before calling
    // proc_close in order to avoid a deadlock
    $return_value = proc_close($process);

    echo "command returned $return_value\n";
}
Brad
  • 159,648
  • 54
  • 349
  • 530
1

You could also consider shared memory if you need more than one listener, but this scenario sounds like you would benefit from using a queue.

Documentation msg_get_queue, msg_receive, msg_send

Example

// Send
if (msg_queue_exists(12345)) {
  $mqh = msg_get_queue(12345);
  $result = msg_send($mqh , 1, 'data', true);
}

// Receive
$mqh = msg_get_queue(12345, 0666);
$mqst = msg_stat_queue($mqh);
while ($mqst['msg_qnum']) {
  msg_receive($mqh, 0, $msgtype, 2048, $data, true);
  // Spawn your process
  $mqst = msg_stat_queue($mqh);
}

Edit

Semaphore functions aren't available on Windows, as suggested above your best bet is to go with popen (unidirectional) or proc_open for bi-directional support.

Martin
  • 6,632
  • 4
  • 25
  • 28
  • This is not an answer to the question. You should leave this as a comment I'd say. This is not about message queues or shared memories but about Inter Process Communication (IPC) via Pipes / Handles. – hakre Aug 12 '12 at 09:42
  • 1
    Perhaps you should read the documentation before you comment. This is a method of IPC. – Martin Aug 12 '12 at 12:23
  • But not IPC via pipes, but via shared memory. And as OP is asking about .exe files I would assume this *is* windows for which what you suggest is not a viable option. Please see:http://www.php.net/manual/en/intro.sem.php - However, generally, you are right, shared memory is *one* way to do IPC - however *not* in this case. – hakre Aug 12 '12 at 12:27
  • 1
    The OP didn't state the solution had to include pipes - and damn I forgot it wasn't available on windows... Good catch. I'll edit the answer – Martin Aug 12 '12 at 12:29
  • Pipes are available on windows (well at least sort of). OP was writing about stdin which also is a pipe IIRC. – hakre Aug 12 '12 at 12:35
  • Yeah, I know - I meant semaphore functions :) - Updated the answer accordingly, thanks for pointing that out. – Martin Aug 12 '12 at 12:38
  • 1
    Just suggest OP should switch OS, so +1 for your solution as it implies that ;) – hakre Aug 12 '12 at 12:55