Well there is a way to use blocking and be able to shutdown the process cleanly. socket_accept() blocking may ignore general signals, but it does not ignore pcntl alarms. An alarm fired every second or so will break you out of a blocking call to socket_accept() (with a warning) and allow your normal flow of logic to detect a shutdown signal i.e. sigterm.
declare(ticks = 1);
private $shutdown = FALSE;
$this->shutdown = TRUE;
public function doit()
$socket = socket_create(AF_INET, SOCK_STREAM, 0);
pcntl_signal(SIGTERM, array(&$this, "sigTerm"));
pcntl_signal(SIGALRM, array(&$this, "sigAlarm"));
if($c = @socket_accept($socket))
echo "Got a connection\n";
echo "Alarm has broken us out of socket_accept blocking, ";
echo "and it is time to shutdown now Dave.\n";
echo "but it is not time to shutdown yet Dave.\n";
$test = new test;
To test the code simply telnet 127.0.0.1 5555 to see it handling connections. Then when you're done a simple killall php should do the trick (just be sure you don't kill any other php process).
I should point out that socket_stream_accept() will respond to signals without the need for an alarm. So if you can, it may be worth going with the stream functions over the cardinal socket functions. (Edit: 04/02/2008) However the stream function response to signals seems a little erratic so I would use an alarm anyway.
UPDATE - 5th March 2008
I was stung by a nasty little oversight that you should know. When reading from a socket, any interrupt (read: alarm) will cause the read to abort. To solve this, after successfully establishing a connection with socket_accept() be sure to run pcntl_alarm(0) then socket_read() and then pcntl_alarm(1) again.