I know this is an old question but hopefully this will still prove helpful to somebody...
Having the process management (fork/exec/wait/kill/signal etc.) in a PHP script called directly from Apache via an http request is definitely not the way to go. As you say, it gets messy very quickly :)
I would suggest that the PHP script called via http is simply a command proxy to a simple server process. If PHP is your preferred language, you can implement both this way.
For example, you can do this with message queues as follows...
You can create a fairly simple PHP server that creates a message queue and wait for
messages to come in. It can then do the work of starting or stopping simulator processes
The remote user selects an operation (start, stop, get output) via a web page form.
This results in an HTTP/POST request sending the form data to your PHP script (I'd do this as an AJAX call so I can send the data and interpret the result without reloading the page)
Your server-side PHP script can interpret the form data and send a command via a message to the PHP server process
Let's illustrate this with some PHP code. I'm keeping this trivial and unsophisticated in the interests of brevity.
PHP Script (web form target)
This is where we interpret our incoming form request and turn it into a message for the server process
<?php
/*
* Responses are sent as simple text strings to be interpreted by
* the client-side JavaScript handling this AJAX call. Responses
* starting with 'ERR:' are errors, responses starting with 'ACK:'
* are acknowledgements. Simply check the first few characters of
* the response in the client-side JavaScript.
*/
header('Content-Type: text/plain; charset=UTF-8);
/*
* Here we define some message types, one per command. These should correspond
* to the command string sent from the web form
*/
$command = array(
'START_SIM' => 1,
'STOP_SIM' => 2,
'GET_STATUS' => 3,
'GET_OUTOUT' => 4
);
$queue_id = 0xbeef; /* An arbitrary message queue id */
$cmd = $_REQUEST['command']; /* The command from the web form */
/* get simulator instance id to act upon, if specified */
if (isset($_REQUEST['id']))
$sim_id = $_REQUEST['id'];
else
$sim_id = ''; /* no sim id? probably a create command */
/* check the message queue exists... */
if (msg_queue_exists($queue_id) === false) {
echo 'ERR:Message queue not found!';
return;
}
/* open the message queue and pass the command on to the server... */
if (($qhandle = msg_get_queue($queue_id)) === false) {
echo 'ERR:Failed to open message queue to server';
return;
}
if (msg_send($qhandle, $command[$cmd], $sim_id) === false)
echo 'ERR:Failed to send command';
else
echo 'ACK:Command sent ok';
?>
PHP Server (run separately on your web server)
And here's an equally simple server...
<?php
/*
* assume the same queue id's and defines as in the
* client code above, etc..
*/
if (($qhandle = msg_get_queue($queue_id)) === false) {
/* emit failure message to log file etc.. */
...
return;
}
while (1) {
if (msg_receive($qhandle, 0, $msgtype, $message,
true, 0, $rc) === false) {
/* log error message ... */
} else {
/*
* Get the client id (in case you want to send
* a reply back to the client) and the
* message data, which is the simulation id.
*
* Remember that we use the message type to
* indicate the command being requested
*/
$client = $message['client'];
$sim_id = $message['msg'];
evaluate_command($client, $msgtype, $sim_id);
}
}
?>
Obviously this is horribly simple, has no error checking and you'll need to write the "evaluate_command()" function yourself. I've just scribbled this down to illustrate the idea (and I've written this off the cuff, so it may be replete with other errors too!)