Close search
Hoa

Hack book de Hoa\Fastcgi

Le protocole FastCGI offre une interface entre un serveur HTTP et un programme externe. Quand PHP est exécuté derrière un serveur CGI, la bibliothèque Hoa\Fastcgi permet de créer facilement de nouvelles exécutions de PHP.

Table des matières

  1. Introduction
    1. Les outils de PHP
  2. Exécuter PHP
    1. Envoyer une requête
    2. Erreurs possibles
  3. Conclusion

Introduction

CGI est un protocole permettant d'assurer la communication entre un serveur HTTP et un programme externe, par exemple PHP, et est spécifié dans la RFC3875. CGI adopte le modèle « une nouvelle exécution par requête ». En général, chaque exécution, ou processus, vit le temps de calculer une réponse à la requête pour ensuite mourir. Toutefois, la charge des serveurs HTTP grandissant, CGI a commencé à montrer ses limites, notamment en terme de vitesse : trop de messages transitaient sur le réseau et la gestion des processus n'était plus efficace. C'est pourquoi, le protocole FastCGI a été proposé afin de résoudre tous ces problèmes. Historiquement, bien que nous utilisons CGI ou FastCGI, ces serveurs sont toujours appelés serveurs CGI.

Le serveur HTTP reçoit des requêtes. Grâce aux en-têtes HTTP, il détecte quel programme externe est concerné par cette requête. Il conserve certaines en-têtes, en ajoute de nouvelles, et envoie une nouvelle requête auprès du serveur CGI. Ce dernier va alors créer un nouveau processus et une fois une réponse obtenue, tuer ce processus puis envoyer la réponse au serveur HTTP, qui s'occupera alors de la retourner au client.

CGI fonctionne en TCP, selon la RFC793, et usuellement, les serveurs écoutent sur le port 9000 et en local (ou sur un réseau protégé) pour des raisons de sécurité.

Les outils de PHP

PHP propose l'outil php-cgi qui permet de démarrer un serveur CGI (reposant sur le protocole FastCGI). Pour l'utiliser :

$ php-cgi -b 127.0.0.1:9000

PHP propose un autre outil : php-fpm, qui utilise FPM (pour FastCGI Process Manager). C'est un serveur CGI dédié à la haute performance et uniquement réservé à PHP. Pour l'utiliser :

$ php-fpm -d listen=127.0.0.1:9000

Attention à bien compiler PHP avec les options --enable-cgi ou --enable-fpm pour obtenir l'outil de votre choix.

Toutefois, il se peut que des serveurs HTTP préfèrent utiliser leur propre serveur CGI, comme c'est le cas avec le mod_php pour Apache.

Exécuter PHP

La bibliothèque Hoa\Fastcgi permet d'une certaine façon de jouer le rôle du serveur HTTP : elle permet d'envoyer des requêtes HTTP sur un serveur CGI et de récupérer une réponse. Ainsi, nous n'aurons pas besoin de serveur HTTP, mais uniquement des outils de PHP.

Envoyer une requête

Pour envoyer une requête, nous devons ouvrir une connexion vers le serveur CGI, et la donner au constructeur de Hoa\Fastcgi\Responder. Ainsi, nous avons le fichier Responder.php :

$fastcgi = new Hoa\Fastcgi\Responder(
    new Hoa\Socket\Client('tcp://127.0.0.1:9000')
);

Pour envoyer une requête, nous utilisons la méthode Hoa\Fastcgi\Responder::send qui prend en premier argument la liste des en-têtes HTTP et en second argument le contenu de la requête (i.e. le corps, optionnel). Les en-têtes minimales sont :

Cette méthode retourne la réponse de la requête. Ainsi, nous préparons notre fichier Echo.php :

<?php

echo 'foobar';

Et nous ajoutons à Responder.php :

var_dump($fastcgi->send([
    'REQUEST_METHOD'  => 'GET',
    'REQUEST_URI'     => '/',
    'SCRIPT_FILENAME' => __DIR__ . DS . 'Echo.php'
]));

/**
 * Will output:
 *    string(6) "foobar"
 */

Les en-têtes HTTP retournées par notre programme PHP n'apparaissent pas dans la réponse. Elles doivent pourtant être retournées au serveur HTTP en tant que réponse au client. Pour les obtenir, il suffit d'appeler la méthode Hoa\Fastcgi\Responder::getResponseHeaders (sœur de Hoa\Fastcgi\Responder::getResponseContent qui retourne la même chose que la méthode Hoa\Fastcgi\Responder::send) :

print_r($fastcgi->getResponseHeaders());
var_dump($fastcgi->getResponseContent());

/**
 * Will output:
 *     Array
 *     (
 *         [x-powered-by] => PHP/x.y.z
 *         [content-type] => text/html
 *     )
 *     string(6) "foobar"
 */

C'est aussi simple que ça !

Erreurs possibles

Le protocole FastCGI peut lever trois erreurs possibles en plus de celles ajoutées par Hoa\Fastcgi\Responder :

Le meilleur moyen de capturer toutes les exceptions est de capturer Hoa\Fastcgi\Exception\Exception :

try {
    $fastcgi->send(…);
} catch (Hoa\Fastcgi\Exception\Exception $e) {
    // compute $e.
}

Actuellement, les serveurs CGI les plus répandus supportent le multiplexage, gèrent bien la charge et supportent tous les rôles. Les erreurs que nous aurons le plus souvent seront des erreurs de réseaux et non de protocole.

Notons que FastCGI supporte trois types de flux : STDIN, STDOUT et STDERR. Le flux entrant sert à envoyer la requête. Le flux sortant sert à recevoir la réponse. Et enfin, le flux d'erreur est concaténé par Hoa\Fastcgi\Responder au flux sortant.

Conclusion

Hoa\Fastcgi permet d'exécuter des programmes PHP (ou d'autres programmes externes) en toute simplicité et rapidement sans se préoccuper de la localisation des binaires PHP, des sous-shells pour les exécuter, de gérer les erreurs etc. Il suffit qu'un serveur CGI soit démarré, c'est tout ce qui est nécessaire.

Manipuler les requêtes FastCGI de cette manière permet également d'en apprendre plus sur PHP et de manipuler les processus PHP d'une autre manière (voir le chapitre sur Hoa\Zombie).

Une erreur ou une suggestion sur la documentation ? Les contributions sont ouvertes !

Comments

menu