(PECL event >= 1.2.6-beta)
EventBufferEvent::sslFilter — Crée un nouveau tampon d'événement SSL, dont les données seront envoyées via un autre tampon d'événement
$base
   ,$underlying
   ,$ctx
   ,$state
   ,$options
     = 0
   Crée un nouveau tampon d'événement SSL, dont les données seront envoyées via un autre tampon d'événement.
Note:
Cette méthode n'est disponible que si
Eventa été compilé avec le support OpenSSL.
base
    Evénement de base associé.
underlying
    Un socket de tampon d'événement à utiliser pour ce SSL.
ctx
    Objet de la classe EventSslContext.
state
    
      Le statut courant de la connexion SSL :
      EventBufferEvent::SSL_OPEN,
      EventBufferEvent::SSL_ACCEPTING ou
      EventBufferEvent::SSL_CONNECTING.
     
options
    Une ou plusieurs options de tampon d'événement.
Retourne un nouvel objet EventBufferEvent SSL.
Exemple #1 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",
            $errno, EventUtil::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 ', $line, 4):
                $this->ev_write($id, "250-STARTTLS\r\n");
                $this->ev_write($id, "250 OK ehlo\r\n");
                break;
            case strncmp('HELO ', $line, 4):
                $this->ev_write($id, "250-STARTTLS\r\n");
                $this->ev_write($id, "250 OK helo\r\n");
                break;
            case strncmp('QUIT', $line, 3):
                $this->ev_write($id, "250 OK quit\r\n");
                $this->ev_close($id);
                break;
            case strncmp('STARTTLS', $line, 3):
                $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();