Yoan Blanc’s weblog

Another lost swiss guy

Pure PHP web server

Yoan BlancSat, 30 Apr 2011, , ,

Over a discussion about doing WebSocket in PHP on Reddit, I realized that I still had a wrong opinion on this language, considering it as being the scripting language tied to a web server (commonly mod_php, php-fpm or fastcgi). I can also be a scripting language for running tasks, like many web frameworks take advantage of. But you can also write your own server in pure PHP, working at the UDP/TCP level.

Let’s build a web server (aka HTTP server).

#!/usr/bin/env php
<?php
$socket = stream_socket_server(
 'tcp://0.0.0.0:8000', $errno, $errstr
);

if (!$socket) {
 echo "$errstr ($errno)", PHP_EOL;
} else {
 while ($conn = stream_socket_accept($socket, -1)) {
  $request = '';
  while (substr($request, -4) !== "\r\n\r\n") {
   $request .= fread($conn, 1024);
  }
  $response = <<<EOS
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 12

Hello World!
EOS;
  fwrite($conn, $response);
  fclose($conn);
 }
}

This is pretty much it. As PHP isn’t multi-threaded maybe the libevent library can help but I didn’t manage to install it. Or you could fork it using the pcntl_fork way. It actually works, badly but works.

Let’s create a WSGI for PHP. Maybe not.

I’m now wondering who would use this for real production stuff. It’s not close from what exists in the other web servers like Unicorn, Gunicorn, … even if they can leverage threads, native code and existing libraries more easily I guess. Not an expert though.

The code is on Github: pure PHP web servers (non-concurrent and concurrent)

Lors d’une récente discussion sur Reddit concernant l’usage de PHP pour des WebSocket ou plutôt son bien fondé, je me suis rendu compte que j’avais encore une mauvaise image de ce dernier. En l’associant à son usage premier, couplé à un server web (via mod_php, php-fpm, fastcgi, …), on oublie qu’il peut servir de langage de script (au même titre que d’autres) et même un peu plus. Il est possible d’écrire un serveur TCP/UDP en PHP pur.

Dans la version simple (voir le code), le serveur n’accepte qu’une seule connexion à la fois, il n’est donc pas très utile en soit.

La seconde forke, c’est-à-dire que le script se duplique ce qui permet d’accepter plus de requêtes à la fois mais crée également un nouveau interpréteur PHP par fois (un fonctionnement commun, PHP n’est pas multithreadé). Il y a bien des fonctions permettant de se servir de la bibliothèque libevent mais je n’ai pas réussi à l’installer. Pour information, libevent est une des bibliothèque permettant à certains serveur web de traîter un grand nombre de connexions simultanées (C10K problem).

Ça ne va pas toute à fait m’enlever l’idée de la tête que PHP est un langage de template avant tout et permet aussi de faire des choses un peu plus poussées. Je demande encore à voir un serveur WebSocket en PHP même si techniquement c’est réalisable.

About

meYoan Blanc is a web developer that lives in Switzerland (rue des Fahys 15, 2000 Neuchâtel) and works as a freelance.

Get my vCard or contact me by phone (skype:yoan.blanc) or email ().

Misc

RSS, list.blogug.ch

This site reflects only my opinion and is not affiliated with anyone else.

copyright 2006-2010 — doSimple.ch