PHP Socket Server? What the pcntl_fork are streams!
By
Christopher Langton
@chrisdlangton
Source Code
{
"require": {
"php": "^7.0",
"sockets/php-stream-socket-server": "^1.4"
}
}
pcntl_fork
When called from a running process pcntl_fork will open a new process on the operating system which will continue to execute in parallel.
Consider:
Ticks

Chewy aside, a tick is a special event that occurs internally in PHP each time it has executed a certain number of statements
Title
Tick syntax
Have you seen the declare function used like this before?
declare(ticks=1) echo 'I haz ticks yo!';
This produces only 1 output, because a tick occurs 1 time per statement, and zend counts ; and {} blocks as a statement.
declare(ticks=1) {{ echo 'tick'; }}
How many ticks printed?
How many printed here?
function tickFunc() { echo 'tick'; }
register_tick_function("tickFunc");
declare(ticks=2);
Ticks cont..
Why do we care about ticks?
- They loosely correspond to the statements in your script
When we fork this can cause unexpected execution blocks internally
- You can register functions to execute when a tick occurs
Great for profiling and debugging, as well as checking resources like mysql are alive
- You can control how many statements it takes to set off a tick
We want this set to 1 statement per tick
You'll encounter some pretty crazy unjustifiable scenarios when forking and leaving zend-ng to figure out statement blocks
Streams
-
Reliable, ordered, interprocess data transfer
-
TCP/IP and open files on the same system are most common
- UDP streams are also possible
- Communication between processes is possible using a socket pair
- WebSockets are implemented using HTTP1.1 streams then UPGRADE via RFC2817
Stream Syntax
const SOCKET_WAIT =
0;
// open a tcp socket on specified open port
$socket = stream_socket_server('tcp://domain:port', $errNo, $errStr);
// zero blocks this process, waits indefinately until a client connects
// errors return as false and complete the while loop
while ($connection = stream_socket_accept($socket, SOCKET_WAIT)) {
// consume 1MB from the stream
$message = stream_socket_recvfrom($connection, 1024);
// peek this to not consume the data
// use the message data, echo it back to the client
fputs($connection, $message);
}
// Don't forget to disconnect sockets
fclose($socket);
Putting it together
- Process forking
resource management - Session leader processes
Zombies! - Ticks
Consistency - Streams
Reliable communication
Questions?
References
- Process Forking
php.net/manual/en/function.pcntl-fork
- Ticks
php.net/manual/en/control-structures.declare
-
Stream Sockets
php.net/manual/en/function.stream-socket-accept
-
Interprocess communitcation
php.net/manual/en/function.stream-socket-pair
- Session leaders
man7.org/linux/man-pages/man3/exit.3
PHP Socket Server? What the pcntl_fork are streams!
By Chris Langton
PHP Socket Server? What the pcntl_fork are streams!
Understanding streams in PHP7, the edge cases when forking processes that hold file descriptors that manage bi-directional messaging.
- 1,760