Inter Process Communication ( IPC ) with PHP

April 26th, 2010

If you found this article, chances are you were looking for it so I won’t go into great detail on defining exactly what IPC is, but the short description is that it’s a method in which you can pass information to and from another process on the server. In my example today, I will be using IPC to build a translator that essentially takes text submitted via a web form and passed it through command line tools and returns your text with a funny dialect applied to it.

Step one in this project is to first get your hands on the command line translator itself, and for that I found the following source archive at this link. My apologies, but the scope of this article doesn’t cover how to compile these translators, and there’s no guarantee it will run on your server, but for informational purposes I will say that I had no trouble building them on a Debian Linux machine.

Now that the translators are compiled and running, we need to build an interface for it in PHP. The interface I’m going to build will be nothing fance, it will consist of a textarea field for our text to be translated, a set of radio boxes to select our target dialect since the archive contains multiple choices, and lastly .. A submit button.

Our code is actually rather simple, but I’m going to give it in parts and explain as I go..

The Form:

Our form is very simple as I mentioned above, but here you go..

1
2
3
4
5
6
7
8
<form method="post">
<textarea name="text" rows="10" cols="40"></textarea><br />
<input type="radio" name="cmd" value="jive">Jive Speak<br />
<input type="radio" name="cmd" value="chef">Swedish Chef<br />
<input type="radio" name="cmd" value="valspeak">Valley Girl<br />
<input type="radio" name="cmd" value="piglatin">Pig Latin<br />
<input type="submit" value="go">
</form>

The PHP:

The heart of this code uses the command proc_open() which requires five arguments.

$command – The command we’re executing.
$descriptor – An array of settings that are used to create our pipes that actually permit the communication.
$pipes – This is a reference and will be become the pipes we write to and read from.
$cwd – The working directory for the command you run, I usually stick to /tmp
$env – This contains any environment variables you wish to set for the command.
Now here is our code ..

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<?php
 
   // We test to see if the posted textarea has anything to translate.
   if ($_POST['text']) {
 
     // We set up our descriptor
     $descriptor = array(    
                         0 => array("pipe", "r"),  // We will read from stdin                             
                         1 => array("pipe", "w"),  // We will write to stdout                          
                         2 => array("file", "/tmp/ipc-errors.txt", "a") // This is the file stderr will send errors to                          
                         );    
 
     // Working directory is set to /tmp
     $cwd = '/tmp';                     
 
     // For this, we don't need to set any environment variables                                                                       
     $env = array();
 
     // Set $command to the value of the radio buttons, this correlates to the command line translator used.
     $command = $_POST['cmd'];
 
     // We now open our process
     $process = proc_open($command, $descriptor, $pipes, $cwd, $env);
 
     // If $process is a valid resource, we've succeeded in launching the process for communication
     if (is_resource($process)) {
 
       // $pipes is now ready for communication                                                                             
       // 0 => is where we write                                                                        
       // 1 => is what we read from                                                                                                                                   
 
       // We use fwrite to pass our text to the command, followed by two carriage returns.
       fwrite($pipes[0], $_POST['text'] . "nrnr");
 
       // And then we close that pipe
       fclose($pipes[0]);
 
       // We echo the results of stream_get_contents, reading from $pipes[1]
       // This will write the "translated" text to the screen below our form.
       echo stream_get_contents($pipes[1]);
 
       // And then we close this pipe as well
       fclose($pipes[1]);
 
       // With the pipes closed ( important! ) we can now close the process safely.                                                                           
       $return_value = proc_close($process);
 
     }
   }
?>

It’s really that simple, this will take user input, modify the text and then echo it back to the screen. To give you an example of the output and just to show you how the dialect modification looks. I will take my opening paragraph now and run it through “Chef”.. Here’s the result:

” Iff yuoo fuoond thees erteecle-a, chunces ere-a yuoo vere-a luukeeng fur it su I vun’t gu intu greet deteeel oon deffeening ixectly vhet IPC is, boot zee shurt descreepshun is thet it’s a methud in vheech yuoo cun pess inffurmeshun tu und frum unuzeer prucess oon zee serfer. In my ixemple-a tudey, I veell be-a useeng IPC tu booeeld a trunsletur thet issenteeelly tekes text soobmeetted feea a veb furm und pessed it thruoogh cummund leene-a tuuls und retoorns yuoor text veet a foonny deeelect eppleeed tu it. Bork Bork Bork! ”

Have fun with it! you can use IPC for all sorts of interesting things, but in my opinion this is a fun use. Please note that it is important to sanitize data that gets passed from your forms before you run it through any command line tools or write it to a database. I did not do that here for simplicity’s sake.

Share on Facebook+1Share on LinkedInShare on MyspacePin it on PinterestSubmit to redditShare on Twitter