public
Last active

This was written by Russell Beattie; I copied it here from a pastebin to give it a permanent home.

  • Download Gist
unicorn.php
PHP
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 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
<?
/*
Simple preforking echo server in PHP.
Russell Beattie (russellbeattie.com)
 
PHP port of http://tomayko.com/writings/unicorn-is-unix
*/
 
/* Allow the script to hang around waiting for connections. */
set_time_limit(0);
 
# Create a socket, bind it to localhost:4242, and start
# listening. Runs once in the parent; all forked children
# inherit the socket's file descriptor.
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($socket,'localhost', 4242);
socket_listen($socket, 10);
 
pcntl_signal(SIGTERM, 'shutdown');
pcntl_signal(SIGINT, 'shutdown');
 
function shutdown($signal){
global $socket;
socket_close($socket);
exit();
}
 
 
# Fork you some child processes. In the parent, the call to
# fork returns immediately with the pid of the child process;
# fork never returns in the child because we exit at the end
# of the block.
for($x = 1; $x <= 3; $x++){
$pid = pcntl_fork();
# pcntl_fork() returns 0 in the child process and the child's
# process id in the parent. So if $pid == 0 then we're in
# the child process.
if($pid == 0){
 
$childpid = posix_getpid();
echo "Child $childpid listening on localhost:4242 \n";
 
while(true){
# This is where the magic happens. accept(2)
# blocks until a new connection is ready to be
# dequeued.
$conn = socket_accept($socket);
 
$message = socket_read($conn,1000,PHP_NORMAL_READ);
socket_write($conn, "Child $childpid echo> $message");
socket_close($conn);
echo "Child $childpid echo'd: $message \n";
}
 
}
}
 
 
#
# Trap interrupts, write a note, and exit immediately in
# parent. This trap is not inherited by the forks because it
# runs after forking has commenced.
try{
 
pcntl_waitpid(-1, $status);
 
} catch (Exception $e) {
 
echo "bailing \n";
exit();
 
}

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.