Close search
Hoa

Hack book of Hoa\Fastcgi

The FastCGI protocol offers an interface between an HTTP server and an external program. When PHP runs behind a CGI server, the Hoa\Fastcgi library allows to easily create new PHP executions.

Table of contents

  1. Introduction
    1. PHP tools
  2. Execute PHP
    1. Send a request
    2. Possible errors
  3. Conclusion

Introduction

CGI is a protocol ensuring the communication between an HTTP server and an external program, for example PHP, and is specified in the RFC3875. CGI embraces the “one new execution per request” model. In general, each execution or processus, lives while computing a response and then dies. However, the HTTP servers load are growing, CGI has began to reach its limits, notably in term of speed: too much messages were exchanged on the network and the processus managing was no longer efficient. That's why the FastCGI protocol has been proposed in order to resolve all these problems. Historically, even though we use CGI or FastCGI, those servers are always called CGI servers.

The HTTP server receives requests. Thanks to HTTP headers, it detects what external program is concerned by this request. It keeps some headers, add new ones, and send a new request to the CGI server. This latter will then create a new processus and when a response is computed, kill it and send the response to the HTTP server, which will send it back to the client.

CGI relies on TCP, according to the RFC793, and usually, the servers listen on the 9000 port and on the local network (or on a protected network) for security reasons.

PHP tools

PHP provides the php-cgi tool that allows to start a CGI server (based on the FastCGI protocol). To use it:

$ php-cgi -b 127.0.0.1:9000

PHP provides another tool: php-fpm that uses FPM (that stands for FastCGI Process Manager). This is a CGI server for high performances and restricted to PHP. To use it:

$ php-fpm -d listen=127.0.0.1:9000

Be careful to compile PHP with the --enable-cgi or --enable-fpm options to get the tool of your choice.

However, it is possible that HTTP servers are likely to use their own CGI server, such as mod_php for Apache.

Execute PHP

The Hoa\Fastcgi library allows in a certain way to play the role of the HTTP server: it allows to send HTTP requests on a CGI server and get a response. Thus, we will not need an HTTP server but only the PHP tools.

Send a request

To send a request, we need to open a connection to the CGI server and give it to the constructor of Hoa\Fastcgi\Responder. Thus, we have the Responder.php file:

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

To send a request, we use the Hoa\Fastcgi\Responder::send method that takes as the first argument a list of HTTP headers and as a the second argument the content of the request (it means the body, optional). The minimal required headers are:

This method returns a response to the request. Thus, we are preparing the Echo.php file:

<?php

echo 'foobar';

And we add in the Responder.php file:

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

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

The HTTP headers returned by our PHP program do not appear in the response. But they need to be returned as a response to the HTTP server for the client. To get them, we only need to call the Hoa\Fastcgi\Responder::getResponseHeaders method (sister of the Hoa\Fastcgi\Responder::getResponseContent that returns the same result that the Hoa\Fastcgi\Responder::send method):

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"
 */

That's it!

Possible errors

The FastCGI protocol can throw three errors in addition to those added by Hoa\Fastcgi\Responder:

The best way to catch all the exceptions is to catch Hoa\Fastcgi\Exception\Exception:

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

So far, the most used CGI servers support the multiplexing, high load and also understand all the roles. The most frequent errors we may encounter will be related to network and not the protocol.

Notice that FastCGI supports three types of stream: STDIN, STDOUT and STDERR. The incoming stream is used to send a request. The outgoing stream is used to receive a response. And finally, the error stream is concatenated to the outgoing stream by Hoa\Fastcgi\Responder.

Conclusion

Hoa\Fastcgi allows to execute PHP programs (or other external programs) in a very simple and fast way without worry about the location of PHP binaries, sub-shells to execute them, manage errors etc. We only need a CGI server to be started.

Manipulating FastCGI requests in this manner allows also to learn more about PHP and to manipulate PHP processus in another way (please, see the Hoa\Zombie library).

An error or a suggestion about the documentation? Contributions are welcome!

Comments

menu