Rechercher une fonction PHP

Exemples

Exemple #1 Client HTTP simple

<?php
// Lecture de la fonction de rappel
function readcb($bev$base) {
    
//$input = $bev->input; //$bev->getInput();

    //$pos = $input->search("TTP");
    
$pos $bev->input->search("TTP");

    while ((
$n $bev->input->remove($buf1024)) > 0) {
        echo 
$buf;
    }
}

// Fonction de rappel de l'événement
function eventcb($bev$events$base) {
    if (
$events EventBufferEvent::CONNECTED) {
        echo 
"Connecté.\n";
    } elseif (
$events & (EventBufferEvent::ERROR EventBufferEvent::EOF)) {
        if (
$events EventBufferEvent::ERROR) {
            echo 
"erreur DNS : "$bev->getDnsErrorString(), PHP_EOL;
        }

        echo 
"Fermeture\n";
        
$base->exit();
        exit(
"Fait !\n");
    }
}

if (
$argc != 3) {
    echo <<<EOS
Trivial HTTP 0.x client
Syntax: php 
{$argv[0]} [hostname] [resource]
Example: php 
{$argv[0]} www.google.com /

EOS;
    exit();
}

$base = new EventBase();

$dns_base = new EventDnsBase($baseTRUE); // Nous utilisons une résolution DNS asynchrone
if (!$dns_base) {
    exit(
"Echec dans l'initialisation de la base DNS\n");
}

$bev = new EventBufferEvent($base/* use internal socket */ NULL,
    
EventBufferEvent::OPT_CLOSE_ON_FREE EventBufferEvent::OPT_DEFER_CALLBACKS,
    
"readcb"/* writecb */ NULL"eventcb"
);
if (!
$bev) {
    exit(
"Echec dans la création du socket bufferevent\n");
}

//$bev->setCallbacks("readcb", /* writecb */ NULL, "eventcb", $base);
$bev->enable(Event::READ Event::WRITE);

$output $bev->output//$bev->getOutput();
if (!$output->add(
    
"GET {$argv[2]} HTTP/1.0\r\n".
    
"Host: {$argv[1]}\r\n".
    
"Connection: Close\r\n\r\n"
)) {
    exit(
"Echec dans l'ajout de la requête dans le buffer de sortie\n");
}

if (!
$bev->connectHost($dns_base$argv[1], 80EventUtil::AF_UNSPEC)) {
    exit(
"Connexion impossible à l'hôte {$argv[1]}\n");
}

$base->dispatch();
?>

L'exemple ci-dessus va afficher quelque chose de similaire à :

Connected.
HTTP/1.1 301 Moved Permanently
Date: Fri, 01 Mar 2013 18:47:48 GMT
Location: http://www.google.co.uk/
Content-Type: text/html; charset=UTF-8
Cache-Control: public, max-age=2592000
Server: gws
Content-Length: 221
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN
Age: 133438
Expires: Sat, 30 Mar 2013 05:39:28 GMT
Connection: close

<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="http://www.google.co.uk/">here</A>.
</BODY></HTML>
Closing
Done

Exemple #2 Client HTTP en utilisant une résolution DNS asynchrone

<?php
/*
 * 1. Connexion à 127.0.0.1 sur le port 80
 * en utilisant EventBufferEvent::connect().
 *
 * 2. Requête /index.cphp via HTTP/1.0
 * en utilisant le buffer de sortie.
 *
 * 3. Lecture asynchrone de la réponse et l'affiche dans stdout.
 */

// Lecture de la fonction de rappel
function readcb($bev$base) {
    
$input $bev->getInput();

    while ((
$n $input->remove($buf1024)) > 0) {
        echo 
$buf;
    }
}

// Fonction de rappel de l'événement
function eventcb($bev$events$base) {
    if (
$events EventBufferEvent::CONNECTED) {
        echo 
"Connecté.\n";
    } elseif (
$events & (EventBufferEvent::ERROR EventBufferEvent::EOF)) {
        if (
$events EventBufferEvent::ERROR) {
            echo 
"Erreur DNS : "$bev->getDnsErrorString(), PHP_EOL;
        }

        echo 
"Fermeture\n";
        
$base->exit();
        exit(
"Fait !\n");
    }
}

$base = new EventBase();

echo 
"étape n°1\n";
$bev = new EventBufferEvent($base/* use internal socket */ NULL,
    
EventBufferEvent::OPT_CLOSE_ON_FREE EventBufferEvent::OPT_DEFER_CALLBACKS);
if (!
$bev) {
    exit(
"Echec lors de la création du socket bufferevent\n");
}

echo 
"étape n°2\n";
$bev->setCallbacks("readcb"/* writecb */ NULL"eventcb"$base);
$bev->enable(Event::READ Event::WRITE);

echo 
"étape n°3\n";
// Envoi de la requête
$output $bev->getOutput();
if (!
$output->add(
    
"GET /index.cphp HTTP/1.0\r\n".
    
"Connection: Close\r\n\r\n"
)) {
    exit(
"Echec lors de l'ajout de la requête dans le buffer de sortie\n");
}

/* COnnexion à l'hôte de façon synchrone.
Nous connaissons l'IP, nous n'avons donc pas besoin de résolution DNS. */
if (!$bev->connect("127.0.0.1:80")) {
    exit(
"Impossible de se connecter à l'hôte\n");
}

// Diffuse les événements en attente
$base->dispatch();
?>

Exemple #3 Serveur d'affichage

<?php
/*
 * Serveur d'affichage simpple basé sur les écoutes de connexion libevent.
 *
 * Utilisation :
 * 1) Dans un terminal, exécutez :
 *
 * $ php listener.php 9881
 *
 * 2) Dans un autre terminal, ouvrez une connexion, i.e. :
 *
 * $ nc 127.0.0.1 9881
 *
 * 3) Commencez à taper. Le serveur devrait répéter les entrées.
 */

class MyListenerConnection {
    private 
$bev$base;

    public function 
__destruct() {
        
$this->bev->free();
    }

    public function 
__construct($base$fd) {
        
$this->base $base;

        
$this->bev = new EventBufferEvent($base$fdEventBufferEvent::OPT_CLOSE_ON_FREE);

        
$this->bev->setCallbacks(array($this"echoReadCallback"), NULL,
            array(
$this"echoEventCallback"), NULL);

        if (!
$this->bev->enable(Event::READ)) {
            echo 
"Echec dans l'activation de READ\n";
            return;
        }
    }

    public function 
echoReadCallback($bev$ctx) {
        
// Copie toutes les données depuis le buffer d'entrée vers le buffer de sortie

        // Variant #1
        
$bev->output->addBuffer($bev->input);

        
/* Variant #2 */
        /*
        $input    = $bev->getInput();
        $output = $bev->getOutput();
        $output->addBuffer($input);
        */
    
}

    public function 
echoEventCallback($bev$events$ctx) {
        if (
$events EventBufferEvent::ERROR) {
            echo 
"Erreur depuis bufferevent\n";
        }

        if (
$events & (EventBufferEvent::EOF EventBufferEvent::ERROR)) {
            
//$bev->free();
            
$this->__destruct();
        }
    }
}

class 
MyListener {
    public 
$base,
        
$listener,
        
$socket;
    private 
$conn = array();

    public function 
__destruct() {
        foreach (
$this->conn as &$c$c NULL;
    }

    public function 
__construct($port) {
        
$this->base = new EventBase();
        if (!
$this->base) {
            echo 
"Impossible d'ouvrir la base de l'événement";
            exit(
1);
        }

        
// Variant #1
        /*
        $this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
        if (!socket_bind($this->socket, '0.0.0.0', $port)) {
            echo "Impossible de lier le socket\n";
            exit(1);
        }
        $this->listener = new EventListener($this->base,
            array($this, "acceptConnCallback"), $this->base,
            EventListener::OPT_CLOSE_ON_FREE | EventListener::OPT_REUSEABLE,
            -1, $this->socket);
         */

        // Variant #2
         
$this->listener = new EventListener($this->base,
             array(
$this"acceptConnCallback"), $this->base,
             
EventListener::OPT_CLOSE_ON_FREE EventListener::OPT_REUSEABLE, -1,
             
"0.0.0.0:$port");

        if (!
$this->listener) {
            echo 
"Impossible de créer l'écouteur";
            exit(
1);
        }

        
$this->listener->setErrorCallback(array($this"accept_error_cb"));
    }

    public function 
dispatch() {
        
$this->base->dispatch();
    }

    
// Cette fonction de rappel est appelée lorsqu'il y a des données à lire sur $bev
    
public function acceptConnCallback($listener$fd$address$ctx) {
        
// Nous avons une nouvelle connexion ! On définit un bufferevent pour elle. */
        
$base $this->base;
        
$this->conn[] = new MyListenerConnection($base$fd);
    }

    public function 
accept_error_cb($listener$ctx) {
        
$base $this->base;

        
fprintf(STDERR"On recoit une erreur %d (%s) sur l'écouteur. "
            
."Arrêt.\n",
            
EventUtil::getLastSocketErrno(),
            
EventUtil::getLastSocketError());

        
$base->exit(NULL);
    }
}

$port 9808;

if (
$argc 1) {
    
$port = (int) $argv[1];
}
if (
$port <= || $port 65535) {
    exit(
"Invalid port");
}

$l = new MyListener($port);
$l->dispatch();
?>

Exemple #4 Serveur d'affichage SSL

<?php
/*
 * Serveur d'affichage SSL
 *
 * Pour tester :
 * 1) Exécutez :
 * $ php examples/ssl-echo-server/server.php 9998
 *
 * 2) dans un autre terminal, exécutez :
 * $ socat - SSL:127.0.0.1:9998,verify=1,cafile=examples/ssl-echo-server/cert.pem
 */

class MySslEchoServer {
    public 
$port,
        
$base,
        
$bev,
        
$listener,
        
$ctx;

    function 
__construct ($port$host "127.0.0.1") {
        
$this->port $port;
        
$this->ctx $this->init_ssl();
        if (!
$this->ctx) {
            exit(
"Echec lors de la création du contexte SSL\n");
        }

        
$this->base = new EventBase();
        if (!
$this->base) {
            exit(
"Impossible d'ouvrir la base de l'événement\n");
        }

        
$this->listener = new EventListener($this->base,
            array(
$this"ssl_accept_cb"), $this->ctx,
            
EventListener::OPT_CLOSE_ON_FREE EventListener::OPT_REUSEABLE,
            -
1"$host:$port");
        if (!
$this->listener) {
            exit(
"Impossible de créer l'écouteur\n");
        }

        
$this->listener->setErrorCallback(array($this"accept_error_cb"));
    }
    function 
dispatch() {
        
$this->base->dispatch();
    }

    
// Cette fonction de rappel est appelée lorsqu'il y a des données à lire sur $bev.
    
function ssl_read_cb($bev$ctx) {
        
$in $bev->input//$bev->getInput();

        
printf("Réception de %zu octets\n"$in->length);
        
printf("----- données ----\n");
        
printf("%ld:\t%s\n", (int) $in->length$in->pullup(-1));

        
$bev->writeBuffer($in);
    }

    
// Cette fonction de rappel est appelée lorsque des erreurs surviennent sur l'écouteur d'événement,
    // i.e. la connexion se ferme, ou une erreur survient
    
function ssl_event_cb($bev$events$ctx) {
        if (
$events EventBufferEvent::ERROR) {
            
// Récupère les erreurs depuis la pile d'erreur SSL
            
while ($err $bev->sslError()) {
                
fprintf(STDERR"Erreur Bufferevent %s.\n"$err);
            }
        }

        if (
$events & (EventBufferEvent::EOF EventBufferEvent::ERROR)) {
            
$bev->free();
        }
    }

    
// Cette fonction de rappel est appelée lorsqu'un client accepte une nouvelle connexion
    
function ssl_accept_cb($listener$fd$address$ctx) {
        
// Nous avons une nouvelle connexion ! On définit un bufferevent pour elle.
        
$this->bev EventBufferEvent::sslSocket($this->base$fd$this->ctx,
            
EventBufferEvent::SSL_ACCEPTINGEventBufferEvent::OPT_CLOSE_ON_FREE);

        if (!
$this->bev) {
            echo 
"Echec lors de la création du buffer SSL\n";
            
$this->base->exit(NULL);
            exit(
1);
        }

        
$this->bev->enable(Event::READ);
        
$this->bev->setCallbacks(array($this"ssl_read_cb"), NULL,
            array(
$this"ssl_event_cb"), NULL);
    }

    
// Cette fonction de rappel est appelée lorsqu'on échoue à définir une nouvelle connexion pour un client
    
function accept_error_cb($listener$ctx) {
        
fprintf(STDERR"On reçoit une erreur %d (%s) sur l'écouteur. "
            
."Arrêt.\n",
            
EventUtil::getLastSocketErrno(),
            
EventUtil::getLastSocketError());

        
$this->base->exit(NULL);
    }

    
// Initialise les structures SSL ; crée un EventSslContext
    // Optionnellement, crée des certificats auto-signés
    
function init_ssl() {
        
// Nous *devons* avoir l'entropie. Sinon, il n'y a aucun intérêt à crypter.
        
if (!EventUtil::sslRandPoll()) {
            exit(
"Echec de EventUtil::sslRandPoll\n");
        }

        
$local_cert __DIR__."/cert.pem";
        
$local_pk   __DIR__."/privkey.pem";

        if (!
file_exists($local_cert) || !file_exists($local_pk)) {
            echo 
"Impossible de lire $local_cert ni $local_pk file. Pour générer une clé\n",
                
"et un certificat auto-signé, exécutez :\n",
                
"  openssl genrsa -out $local_pk 2048\n",
                
"  openssl req -new -key $local_pk -out cert.req\n",
                
"  openssl x509 -req -days 365 -in cert.req -signkey $local_pk -out $local_cert\n";

            return 
FALSE;
        }

        
$ctx = new EventSslContext(EventSslContext::SSLv3_SERVER_METHOD, array (
             
EventSslContext::OPT_LOCAL_CERT  => $local_cert,
             
EventSslContext::OPT_LOCAL_PK    => $local_pk,
             
//EventSslContext::OPT_PASSPHRASE  => "echo server",
             
EventSslContext::OPT_VERIFY_PEER => true,
             
EventSslContext::OPT_ALLOW_SELF_SIGNED => false,
        ));

        return 
$ctx;
    }
}

// Autorise l'écrasement du port
$port 9999;
if (
$argc 1) {
    
$port = (int) $argv[1];
}
if (
$port <= || $port 65535) {
    exit(
"Port invalide\n");
}


$l = new MySslEchoServer($port);
$l->dispatch();
?>

Exemple #5 Gestionnaire de signal

<?php
/*
Dans un terminal, exécutez :

$ php examples/signal.php

Dans un autre terminal, trouvez le pid et envoyé le signal SIGTERM, i.e. :

$ ps aux | grep examp
ruslan    3976  0.2  0.0 139896 11256 pts/1    S+   10:25   0:00 php examples/signal.php
ruslan    3978  0.0  0.0   9572   864 pts/2    S+   10:26   0:00 grep --color=auto examp
$ kill -TERM 3976

Dans le premier terminal, vous devriez attrapper ce qui suit :

On attrappe le signal 15
*/
class MyEventSignal {
    private 
$base;

    function 
__construct($base) {
        
$this->base $base;
    }

    function 
eventSighandler($no$c) {
        echo 
"On attrappe le signal $no\n";
        
event_base_loopexit($c->base);
    }
}

$base event_base_new();
$c    = new MyEventSignal($base);
$no   SIGTERM;
$ev   evsignal_new($base$no, array($c,'eventSighandler'), $c);

evsignal_add($ev);

event_base_loop($base);
?>

Exemple #6 Utilisation d'une boucle libevent pour réaliser les requêtes de l'extension `eio'

<?php
// Fonction de rappel pour eio_nop()
function my_nop_cb($d$r) {
    echo 
"étape 6\n";
}

$dir "/tmp/abc-eio-temp";
if (
file_exists($dir)) {
    
rmdir($dir);
}

echo 
"étape 1\n";

$base = new EventBase();

echo 
"étape 2\n";

eio_init();

eio_mkdir($dir0750EIO_PRI_DEFAULT"my_nop_cb");

$event = new Event($baseeio_get_event_stream(),
    
Event::READ Event::PERSIST, function ($fd$events$base) {
    echo 
"step 5\n";

    while (
eio_nreqs()) {
        
eio_poll();
    }

    
$base->stop();
}, 
$base);

echo 
"étape 3\n";

$event->add();

echo 
"étape 4\n";

$base->dispatch();

echo 
"Fait !\n";
?>

Exemple #7 Divers

<?php
/* {{{ Configuration & méthodes supportées */
echo "Méthodes supportées :\n";
foreach (
Event::getSupportedMethods() as $m) {
    echo 
$mPHP_EOL;
}

// On désactive la méthode "select"
$cfg = new EventConfig();
if (
$cfg->avoidMethod("select")) {
    echo 
"La méthode `select' a été désactivée\n";
}

// Crée un event_base associé à la configuration
$base = new EventBase($cfg);
echo 
"Méthode d'événement utilisée : "$base->getMethod(), PHP_EOL;

echo 
"fonctionalités :\n";
$features $base->getFeatures();
(
$features EventConfig::FEATURE_ET) and print("ET - edge-triggered IO\n");
(
$features EventConfig::FEATURE_O1) and print("O1 - O(1) operation for adding/deletting events\n");
(
$features EventConfig::FEATURE_FDS) and print("FDS - arbitrary file descriptor types, and not just sockets\n");

// Nécessite la fonctionalité FDS
if ($cfg->requireFeatures(EventConfig::FEATURE_FDS)) {
    echo 
"La fonctionalité FDS est maintenant requise\n";

    
$base = new EventBase($cfg);
    (
$base->getFeatures() & EventConfig::FEATURE_FDS)
        and print(
"FDS - type de descripteur de fichiers arbitraire, et non uniquement les sockets\n");
}
/* }}} */

/* {{{ Base */
$base = new EventBase();
$event = new Event($baseSTDINEvent::READ Event::PERSIST, function ($fd$events$arg) {
    static 
$max_iterations 0;

    if (++
$max_iterations >= 5) {
        
/* on sort après 5 itérations avec un délai maximal d'attente de 2.33 secondes */
        
echo "Arrêt...\n";
        
$arg[0]->exit(2.33);
    }

    echo 
fgets($fd);
}, array (&
$base));

$event->add();
$base->loop();
/* Base }}} */
?>

Exemple #8 Serveur HTTP simple

<?php
/*
 * Serveur HTTP simple.
 *
 * Pour le tester :
 * 1) Exécutez-le sur le port de votre choix, i.e. :
 * $ php examples/http.php 8010
 * 2) Dans un autre terminal, connectez-vous sur une adresse de ce port
 * et effectuez des requêtes GET ou POST (les autres types sont désactivées dans cet exemple), i.e. :
 * $ nc -t 127.0.0.1 8010
 * POST /about HTTP/1.0
 * Content-Type: text/plain
 * Content-Length: 4
 * Connection: close
 * (press Enter)
 *
 * Il devrait afficher :
 * a=12
 * HTTP/1.0 200 OK
 * Content-Type: text/html; charset=ISO-8859-1
 * Connection: close
 *
 * $ nc -t 127.0.0.1 8010
 * GET /dump HTTP/1.0
 * Content-Type: text/plain
 * Content-Encoding: UTF-8
 * Connection: close
 * (press Enter)
 *
 * Il devrait afficher :
 * HTTP/1.0 200 OK
 * Content-Type: text/html; charset=ISO-8859-1
 * Connection: close
 * (press Enter)
 *
 * $ nc -t 127.0.0.1 8010
 * GET /unknown HTTP/1.0
 * Connection: close
 *
 * Il devrait afficher :
 * HTTP/1.0 200 OK
 * Content-Type: text/html; charset=ISO-8859-1
 * Connection: close
 *
 * 3) Voir ce que le serveur affiche dans le terminal précédent.
 */

function _http_dump($req$data) {
    static 
$counter      0;
    static 
$max_requests 2;

    if (++
$counter >= $max_requests)  {
        echo 
"Le compteur a atteint le nombre maximal de requête ($max_requests). Sortie !\n";
        exit();
    }

    echo 
__METHOD__" called\n";
    echo 
"Requête :"var_dump($req);
    echo 
"Données :"var_dump($data);

    echo 
"\n===== DUMP =====\n";
    echo 
"Commande :"$req->getCommand(), PHP_EOL;
    echo 
"URI :"$req->getUri(), PHP_EOL;
    echo 
"En-têtes en entrée :"var_dump($req->getInputHeaders());
    echo 
"En-têtes en sortie :"var_dump($req->getOutputHeaders());

    echo 
"\n >> Envoi de la réponse ...";
    
$req->sendReply(200"OK");
    echo 
"OK\n";

    echo 
"\n >> Lecture du buffer d'entrée ...\n";
    
$buf $req->getInputBuffer();
    while (
$s $buf->readLine(EventBuffer::EOL_ANY)) {
        echo 
$sPHP_EOL;
    }
    echo 
"Il n'y a plus de données dans le buffer\n";
}

function 
_http_about($req) {
    echo 
__METHOD__PHP_EOL;
    echo 
"URI : "$req->getUri(), PHP_EOL;
    echo 
"\n >> Envoi de la réponse ...";
    
$req->sendReply(200"OK");
    echo 
"OK\n";
}

function 
_http_default($req$data) {
    echo 
__METHOD__PHP_EOL;
    echo 
"URI: "$req->getUri(), PHP_EOL;
    echo 
"\n >> Envoi de la réponse ...";
    
$req->sendReply(200"OK");
    echo 
"OK\n";
}

$port 8010;
if (
$argc 1) {
    
$port = (int) $argv[1];
}
if (
$port <= || $port 65535) {
    exit(
"Port invalide");
}

$base = new EventBase();
$http = new EventHttp($base);
$http->setAllowedMethods(EventHttpRequest::CMD_GET EventHttpRequest::CMD_POST);

$http->setCallback("/dump""_http_dump", array(48));
$http->setCallback("/about""_http_about");
$http->setDefaultCallback("_http_default""valeur de données personnalisées");

$http->bind("0.0.0.0"8010);
$base->loop();
?>

L'exemple ci-dessus va afficher quelque chose de similaire à :

a=12
HTTP/1.0 200 OK
Content-Type: text/html; charset=ISO-8859-1
Connection: close

HTTP/1.0 200 OK
Content-Type: text/html; charset=ISO-8859-1
Connection: close
(press Enter)

HTTP/1.0 200 OK
Content-Type: text/html; charset=ISO-8859-1
Connection: close

Exemple #9 Serveur HTTPS simple

<?php
/*
 * Serveur HTTPS simple.
 *
 * 1) Exécutez le serveur : `php examples/https.php 9999`
 * 2) Testez le : `php examples/ssl-connection.php 9999`
 */

function _http_dump($req$data) {
    static 
$counter      0;
    static 
$max_requests 200;

    if (++
$counter >= $max_requests)  {
        echo 
"Le compteur a atteint le nombre maximal de requêtes ($max_requests). Sortie\n";
        exit();
    }

    echo 
__METHOD__" appelée\n";
    echo 
"Requête :"var_dump($req);
    echo 
"Données :"var_dump($data);

    echo 
"\n===== DUMP =====\n";
    echo 
"Commande :"$req->getCommand(), PHP_EOL;
    echo 
"URI :"$req->getUri(), PHP_EOL;
    echo 
"En-têtes d'entrée :"var_dump($req->getInputHeaders());
    echo 
"En-têtes de sortie :"var_dump($req->getOutputHeaders());

    echo 
"\n >> Envoi de la réponse ...";
    
$req->sendReply(200"OK");
    echo 
"OK\n";

    
$buf $req->getInputBuffer();
    echo 
"\n >> Lecture du buffer d'entrée ("$buf->length") ...\n";
    while (
$s $buf->read(1024)) {
        echo 
$s;
    }
    echo 
"\nIl n'y a plus de données dans le buffer\n";
}

function 
_http_about($req) {
    echo 
__METHOD__PHP_EOL;
    echo 
"URI : "$req->getUri(), PHP_EOL;
    echo 
"\n >> Envoi de la réponse ...";
    
$req->sendReply(200"OK");
    echo 
"OK\n";
}

function 
_http_default($req$data) {
    echo 
__METHOD__PHP_EOL;
    echo 
"URI: "$req->getUri(), PHP_EOL;
    echo 
"\n >> Envoi de la réponse ...";
    
$req->sendReply(200"OK");
    echo 
"OK\n";
}

function 
_http_400($req) {
    
$req->sendError(400);
}

function 
_init_ssl() {
    
$local_cert __DIR__."/ssl-echo-server/cert.pem";
    
$local_pk   __DIR__."/ssl-echo-server/privkey.pem";

    
$ctx = new EventSslContext(EventSslContext::SSLv3_SERVER_METHOD, array (
        
EventSslContext::OPT_LOCAL_CERT  => $local_cert,
        
EventSslContext::OPT_LOCAL_PK    => $local_pk,
        
//EventSslContext::OPT_PASSPHRASE  => "test",
        
EventSslContext::OPT_ALLOW_SELF_SIGNED => true,
    ));

    return 
$ctx;
}

$port 9999;
if (
$argc 1) {
    
$port = (int) $argv[1];
}
if (
$port <= || $port 65535) {
    exit(
"Port invalide");
}
$ip '0.0.0.0';

$base = new EventBase();
$ctx  _init_ssl();
$http = new EventHttp($base$ctx);
$http->setAllowedMethods(EventHttpRequest::CMD_GET EventHttpRequest::CMD_POST);

$http->setCallback("/dump""_http_dump", array(48));
$http->setCallback("/about""_http_about");
$http->setCallback("/err400""_http_400");
$http->setDefaultCallback("_http_default""Valeur des données personnalisées");

$http->bind($ip$port);
$base->dispatch();

Exemple #10 Connexion OpenSSL

<?php
/*
 * Exemple de Client OpenSSL.
 *
 * Utilisation :
 * 1) Exécutez un serveur, i.e. :
 * $ php examples/https.php 9999
 *
 * 2) Lancez le client dans un autre terminal :
 * $ php examples/ssl-connection.php 9999
 */

function _request_handler($req$base) {
    echo 
__FUNCTION__PHP_EOL;

    if (
is_null($req)) {
        echo 
"Délai d'attente maximal atteint\n";
    } else {
        
$response_code $req->getResponseCode();

        if (
$response_code == 0) {
            echo 
"Connexion refusée\n";
        } elseif (
$response_code != 200) {
            echo 
"Réponse innatendue : $response_code\n";
        } else {
            echo 
"Succès : $response_code\n";
            
$buf $req->getInputBuffer();
            echo 
"Corps :\n";
            while (
$s $buf->readLine(EventBuffer::EOL_ANY)) {
                echo 
$sPHP_EOL;
            }
        }
    }

    
$base->exit(NULL);
}

function 
_init_ssl() {
    
$ctx = new EventSslContext(EventSslContext::SSLv3_CLIENT_METHOD, array ());

    return 
$ctx;
}


// Autorise l'écrasement du port
$port 9999;
if (
$argc 1) {
    
$port = (int) $argv[1];
}
if (
$port <= || $port 65535) {
    exit(
"Port invalide\n");
}
$host '127.0.0.1';

$ctx _init_ssl();
if (!
$ctx) {
    
trigger_error("Echec lors de la création du contexte SSL"E_USER_ERROR);
}

$base = new EventBase();
if (!
$base) {
    
trigger_error("Echec dans l'initialisation de la base d'événement"E_USER_ERROR);
}

$conn = new EventHttpConnection($baseNULL$host$port$ctx);
$conn->setTimeout(50);

$req = new EventHttpRequest("_request_handler"$base);
$req->addHeader("Host"$hostEventHttpRequest::OUTPUT_HEADER);
$buf $req->getOutputBuffer();
$buf->add("<html>HTML TEST</html>");
//$req->addHeader("Content-Length", $buf->length, EventHttpRequest::OUTPUT_HEADER);
//$req->addHeader("Connection", "close", EventHttpRequest::OUTPUT_HEADER);
$conn->makeRequest($reqEventHttpRequest::CMD_POST"/dump");

$base->dispatch();
echo 
"FIN\n";
?>

Exemple #11 Exemple avec EventHttpConnection::makeRequest()

<?php
function _request_handler($req$base) {
    echo 
__FUNCTION__PHP_EOL;

    if (
is_null($req)) {
        echo 
"Délai d'attente maximal atteint\n";
    } else {
        
$response_code $req->getResponseCode();

        if (
$response_code == 0) {
            echo 
"Connexion refusée\n";
        } elseif (
$response_code != 200) {
            echo 
"Réponse innatendue : $response_code\n";
        } else {
            echo 
"Succès : $response_code\n";
            
$buf $req->getInputBuffer();
            echo 
"Corps :\n";
            while (
$s $buf->readLine(EventBuffer::EOL_ANY)) {
                echo 
$sPHP_EOL;
            }
        }
    }

    
$base->exit(NULL);
}

$address "127.0.0.1";
$port 80;

$base = new EventBase();
$conn = new EventHttpConnection($baseNULL$address$port);
$conn->setTimeout(5);
$req = new EventHttpRequest("_request_handler"$base);

$req->addHeader("Host"$addressEventHttpRequest::OUTPUT_HEADER);
$req->addHeader("Content-Length""0"EventHttpRequest::OUTPUT_HEADER);
$conn->makeRequest($reqEventHttpRequest::CMD_GET"/index.cphp");

$base->loop();
?>

L'exemple ci-dessus va afficher quelque chose de similaire à :

_request_handler
Succès : 200
Corps :
PHP, date:
2013-03-13T20:27:52+05:00

Exemple #12 Ecoute d'une connexion en se basant sur un socket de domaine Unix

<?php
/*
 * Serveur d'écoute en se basant sur un écouteur de connexion libevent.
 *
 * Utilisation :
 * 1) Dans un terminal, exécutez :
 *
 * $ php unix-domain-listener.php [path-to-socket]
 *
 * 2) Dans un autre terminal, ouvrez la connexion
 * vers le socket, i.e. :
 *
 * $ socat - GOPEN:/tmp/1.sock
 *
 * 3) Commencez à taper. Le serveur doit répéter les entrées.
 */

class MyListenerConnection {
    private 
$bev$base;

    public function 
__destruct() {
        if (
$this->bev) {
            
$this->bev->free();
        }
    }

    public function 
__construct($base$fd) {
        
$this->base $base;

        
$this->bev = new EventBufferEvent($base$fdEventBufferEvent::OPT_CLOSE_ON_FREE);

        
$this->bev->setCallbacks(array($this"echoReadCallback"), NULL,
            array(
$this"echoEventCallback"), NULL);

        if (!
$this->bev->enable(Event::READ)) {
            echo 
"Echec dans l'activation de READ\n";
            return;
        }
    }

    public function 
echoReadCallback($bev$ctx) {
        
// Copie toutes les données depuis le buffer d'entrée dans le buffer de sortie
        
$bev->output->addBuffer($bev->input);
    }

    public function 
echoEventCallback($bev$events$ctx) {
        if (
$events EventBufferEvent::ERROR) {
            echo 
"Erreur depuis bufferevent\n";
        }

        if (
$events & (EventBufferEvent::EOF EventBufferEvent::ERROR)) {
            
$bev->free();
            
$bev NULL;
        }
    }
}

class 
MyListener {
    public 
$base,
        
$listener,
        
$socket;
    private 
$conn = array();

    public function 
__destruct() {
        foreach (
$this->conn as &$c$c NULL;
    }

    public function 
__construct($sock_path) {
        
$this->base = new EventBase();
        if (!
$this->base) {
            echo 
"Couldn't open event base";
            exit(
1);
        }

        if (
file_exists($sock_path)) {
            
unlink($sock_path);
        }

         
$this->listener = new EventListener($this->base,
             array(
$this"acceptConnCallback"), $this->base,
             
EventListener::OPT_CLOSE_ON_FREE EventListener::OPT_REUSEABLE, -1,
             
"unix:$sock_path");

        if (!
$this->listener) {
            
trigger_error("Impossible de créer l'écouteur"E_USER_ERROR);
        }

        
$this->listener->setErrorCallback(array($this"accept_error_cb"));
    }

    public function 
dispatch() {
        
$this->base->dispatch();
    }

    
// Cette fonction de rappel sera appelée lorsqu'il y aura des données à lire sur $bev
    
public function acceptConnCallback($listener$fd$address$ctx) {
        
// Nous avons une nouvelle connexion ! On définit un bufferevent pour elle. */
        
$base $this->base;
        
$this->conn[] = new MyListenerConnection($base$fd);
    }

    public function 
accept_error_cb($listener$ctx) {
        
$base $this->base;

        
fprintf(STDERR"On reçoit une erreur %d (%s) sur l'écouteur. "
            
."Shutting down.\n",
            
EventUtil::getLastSocketErrno(),
            
EventUtil::getLastSocketError());

        
$base->exit(NULL);
    }
}

if (
$argc <= 1) {
    exit(
"Le chemin vers le socket n'est pas fourni\n");
}
$sock_path $argv[1];

$l = new MyListener($sock_path);
$l->dispatch();
?>

Exemple #13 Exemple de serveur SMTP

<?php
 
/*
 * Auteur : Andrew Rose <hello at andrewrose dot co dot uk>
 *
 * Utilisation :
 * 1) On prépare le certificat cert.pem et la clé privée privkey.pem.
 * 2) On démarre le script du serveur
 * 3) On ouvre la connexion TLS, i.e. :
 *      $ openssl s_client -connect localhost:25 -starttls smtp -crlf
 * 4) On commence à tester les commandes listées dans la méthode `cmd` ci-dessous.
 */

class Handler {
    public 
$domainName FALSE;
    public 
$connections = [];
    public 
$buffers = [];
    public 
$maxRead 256000;

    public function 
__construct() {
        
$this->ctx = new EventSslContext(EventSslContext::SSLv3_SERVER_METHOD, [
            
EventSslContext::OPT_LOCAL_CERT  => 'cert.pem',
            
EventSslContext::OPT_LOCAL_PK    => 'privkey.pem',
            
//EventSslContext::OPT_PASSPHRASE  => '',
            
EventSslContext::OPT_VERIFY_PEER => false// modifier en TRUE avec les certificats authentiques
            
EventSslContext::OPT_ALLOW_SELF_SIGNED => true // modifier en FALSE avec les certificats authentiques
        
]);

        
$this->base = new EventBase();
        if (!
$this->base) {
            exit(
"Impossible d'ouvrir la base de l'événement\n");
        }

        if (!
$this->listener = new EventListener($this->base,
            [
$this'ev_accept'],
            
$this->ctx,
            
EventListener::OPT_CLOSE_ON_FREE EventListener::OPT_REUSEABLE,
            -
1,
            
'0.0.0.0:25'))
        {
            exit(
"Impossible de créer l'écouteur\n");
        }

        
$this->listener->setErrorCallback([$this'ev_error']);
        
$this->base->dispatch();
    }

    public function 
ev_accept($listener$fd$address$ctx) {
        static 
$id 0;
        
$id += 1;

        
$this->connections[$id]['clientData'] = '';
        
$this->connections[$id]['cnx'] = new EventBufferEvent($this->base$fd,
            
EventBufferEvent::OPT_CLOSE_ON_FREE);

        if (!
$this->connections[$id]['cnx']) {
            echo 
"Echec lors de la création du buffer\n";
            
$this->base->exit(NULL);
            exit(
1);
        }

        
$this->connections[$id]['cnx']->setCallbacks([$this"ev_read"], NULL,
            [
$this'ev_error'], $id);
        
$this->connections[$id]['cnx']->enable(Event::READ Event::WRITE);

        
$this->ev_write($id'220 '.$this->domainName." wazzzap?\r\n");
    }

    function 
ev_error($listener$ctx) {
        
$errno EventUtil::getLastSocketErrno();

        
fprintf(STDERR"On reçoit l'erreur %d (%s) sur l'écouteur. On stoppe.\n",
            
$errnoEventUtil::getLastSocketError());

        if (
$errno != 0) {
            
$this->base->exit(NULL);
            exit();
        }
    }

    public function 
ev_close($id) {
        
$this->connections[$id]['cnx']->disable(Event::READ Event::WRITE);
        unset(
$this->connections[$id]);
    }

    protected function 
ev_write($id$string) {
        echo 
'S('.$id.'): '.$string;
        
$this->connections[$id]['cnx']->write($string);
    }

    public function 
ev_read($buffer$id) {
        while(
$buffer->input->length 0) {
            
$this->connections[$id]['clientData'] .= $buffer->input->read($this->maxRead);
            
$clientDataLen strlen($this->connections[$id]['clientData']);

            if(
$this->connections[$id]['clientData'][$clientDataLen-1] == "\n"
                
&& $this->connections[$id]['clientData'][$clientDataLen-2] == "\r")
            {
                
// Supprime les caractères \r\n à la fin
                
$line substr($this->connections[$id]['clientData'], 0,
                    
strlen($this->connections[$id]['clientData']) - 2);

                
$this->connections[$id]['clientData'] = '';
                
$this->cmd($buffer$id$line);
            }
        }
    }

    protected function 
cmd($buffer$id$line) {
        switch (
$line) {
            case 
strncmp('EHLO '$line4):
                
$this->ev_write($id"250-STARTTLS\r\n");
                
$this->ev_write($id"250 OK ehlo\r\n");
                break;

            case 
strncmp('HELO '$line4):
                
$this->ev_write($id"250-STARTTLS\r\n");
                
$this->ev_write($id"250 OK helo\r\n");
                break;

            case 
strncmp('QUIT'$line3):
                
$this->ev_write($id"250 OK quit\r\n");
                
$this->ev_close($id);
                break;

            case 
strncmp('STARTTLS'$line3):
                
$this->ev_write($id"220 Ready to start TLS\r\n");
                
$this->connections[$id]['cnx'] = EventBufferEvent::sslFilter($this->base,
                    
$this->connections[$id]['cnx'], $this->ctx,
                    
EventBufferEvent::SSL_ACCEPTING,
                    
EventBufferEvent::OPT_CLOSE_ON_FREE);
                
$this->connections[$id]['cnx']->setCallbacks([$this"ev_read"], NULL, [$this'ev_error'], $id);
                
$this->connections[$id]['cnx']->enable(Event::READ Event::WRITE);
                break;

            default:
                echo 
'Commande inconnue : '.$line."\n";
                break;
        }
    }
}

new 
Handler();
Rechercher une fonction PHP

Version en cache

24/12/2024 13:25:06 Cette version de la page est en cache (à la date du 24/12/2024 13:25:06) afin d'accélérer le traitement. Vous pouvez activer le mode utilisateur dans le menu en haut pour afficher la dernère version de la page.

Document créé le 30/01/2003, dernière modification le 26/10/2018
Source du document imprimé : https://www.gaudry.be/php-rf-event.examples.html

L'infobrol est un site personnel dont le contenu n'engage que moi. Le texte est mis à disposition sous licence CreativeCommons(BY-NC-SA). Plus d'info sur les conditions d'utilisation et sur l'auteur.

Références

  1. Consulter le document html Langue du document :fr Manuel PHP : http://php.net

Ces références et liens indiquent des documents consultés lors de la rédaction de cette page, ou qui peuvent apporter un complément d'information, mais les auteurs de ces sources ne peuvent être tenus responsables du contenu de cette page.
L'auteur de ce site est seul responsable de la manière dont sont présentés ici les différents concepts, et des libertés qui sont prises avec les ouvrages de référence. N'oubliez pas que vous devez croiser les informations de sources multiples afin de diminuer les risques d'erreurs.

Table des matières Haut