|  | 
 
 Examples
  Example #1 Simple HTTP client 
<?php// Read callback
 function readcb($bev, $base) {
 //$input = $bev->input; //$bev->getInput();
 
 //$pos = $input->search("TTP");
 $pos = $bev->input->search("TTP");
 
 while (($n = $bev->input->remove($buf, 1024)) > 0) {
 echo $buf;
 }
 }
 
 // Event callback
 function eventcb($bev, $events, $base) {
 if ($events & EventBufferEvent::CONNECTED) {
 echo "Connected.\n";
 } elseif ($events & (EventBufferEvent::ERROR | EventBufferEvent::EOF)) {
 if ($events & EventBufferEvent::ERROR) {
 echo "DNS error: ", $bev->getDnsErrorString(), PHP_EOL;
 }
 
 echo "Closing\n";
 $base->exit();
 exit("Done\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($base, TRUE); // We'll use async DNS resolving
 if (!$dns_base) {
 exit("Failed to init DNS Base\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("Failed creating bufferevent socket\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("Failed adding request to output buffer\n");
 }
 
 if (!$bev->connectHost($dns_base, $argv[1], 80, EventUtil::AF_UNSPEC)) {
 exit("Can't connect to host {$argv[1]}\n");
 }
 
 $base->dispatch();
 ?>
 The above example will output
something similar to:
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
 
  Example #2 HTTP client using asynchronous DNS resolver 
<?php/*
 * 1. Connect to 127.0.0.1 at port 80
 * by means of EventBufferEvent::connect().
 *
 * 2. Request /index.cphp via HTTP/1.0
 * using the output buffer.
 *
 * 3. Asyncronously read the response and print it to stdout.
 */
 
 // Read callback
 function readcb($bev, $base) {
 $input = $bev->getInput();
 
 while (($n = $input->remove($buf, 1024)) > 0) {
 echo $buf;
 }
 }
 
 // Event callback
 function eventcb($bev, $events, $base) {
 if ($events & EventBufferEvent::CONNECTED) {
 echo "Connected.\n";
 } elseif ($events & (EventBufferEvent::ERROR | EventBufferEvent::EOF)) {
 if ($events & EventBufferEvent::ERROR) {
 echo "DNS error: ", $bev->getDnsErrorString(), PHP_EOL;
 }
 
 echo "Closing\n";
 $base->exit();
 exit("Done\n");
 }
 }
 
 $base = new EventBase();
 
 echo "step 1\n";
 $bev = new EventBufferEvent($base, /* use internal socket */ NULL,
 EventBufferEvent::OPT_CLOSE_ON_FREE | EventBufferEvent::OPT_DEFER_CALLBACKS);
 if (!$bev) {
 exit("Failed creating bufferevent socket\n");
 }
 
 echo "step 2\n";
 $bev->setCallbacks("readcb", /* writecb */ NULL, "eventcb", $base);
 $bev->enable(Event::READ | Event::WRITE);
 
 echo "step 3\n";
 // Send request
 $output = $bev->getOutput();
 if (!$output->add(
 "GET /index.cphp HTTP/1.0\r\n".
 "Connection: Close\r\n\r\n"
 )) {
 exit("Failed adding request to output buffer\n");
 }
 
 /* Connect to the host syncronously.
 We know the IP, and don't need to resolve DNS. */
 if (!$bev->connect("127.0.0.1:80")) {
 exit("Can't connect to host\n");
 }
 
 // Dispatch pending events
 $base->dispatch();
 ?>
 
  Example #3 Echo server 
<?php/*
 * Simple echo server based on libevent's connection listener.
 *
 * Usage:
 * 1) In one terminal window run:
 *
 * $ php listener.php 9881
 *
 * 2) In another terminal window open up connection, e.g.:
 *
 * $ nc 127.0.0.1 9881
 *
 * 3) start typing. The server should repeat the input.
 */
 
 class MyListenerConnection {
 private $bev, $base;
 
 public function __destruct() {
 $this->bev->free();
 }
 
 public function __construct($base, $fd) {
 $this->base = $base;
 
 $this->bev = new EventBufferEvent($base, $fd, EventBufferEvent::OPT_CLOSE_ON_FREE);
 
 $this->bev->setCallbacks(array($this, "echoReadCallback"), NULL,
 array($this, "echoEventCallback"), NULL);
 
 if (!$this->bev->enable(Event::READ)) {
 echo "Failed to enable READ\n";
 return;
 }
 }
 
 public function echoReadCallback($bev, $ctx) {
 // Copy all the data from the input buffer to the output buffer
 
 // 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 "Error from 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 "Couldn't open event base";
 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 "Unable to bind 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 "Couldn't create listener";
 exit(1);
 }
 
 $this->listener->setErrorCallback(array($this, "accept_error_cb"));
 }
 
 public function dispatch() {
 $this->base->dispatch();
 }
 
 // This callback is invoked when there is data to read on $bev
 public function acceptConnCallback($listener, $fd, $address, $ctx) {
 // We got a new connection! Set up a bufferevent for it. */
 $base = $this->base;
 $this->conn[] = new MyListenerConnection($base, $fd);
 }
 
 public function accept_error_cb($listener, $ctx) {
 $base = $this->base;
 
 fprintf(STDERR, "Got an error %d (%s) on the listener. "
 ."Shutting down.\n",
 EventUtil::getLastSocketErrno(),
 EventUtil::getLastSocketError());
 
 $base->exit(NULL);
 }
 }
 
 $port = 9808;
 
 if ($argc > 1) {
 $port = (int) $argv[1];
 }
 if ($port <= 0 || $port > 65535) {
 exit("Invalid port");
 }
 
 $l = new MyListener($port);
 $l->dispatch();
 ?>
 
  Example #4 SSL echo server 
<?php/*
 * SSL echo server
 *
 * To test:
 * 1) Run:
 * $ php examples/ssl-echo-server/server.php 9998
 *
 * 2) in another terminal window run:
 * $ 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("Failed creating SSL context\n");
 }
 
 $this->base = new EventBase();
 if (!$this->base) {
 exit("Couldn't open event base\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("Couldn't create listener\n");
 }
 
 $this->listener->setErrorCallback(array($this, "accept_error_cb"));
 }
 function dispatch() {
 $this->base->dispatch();
 }
 
 // This callback is invoked when there is data to read on $bev.
 function ssl_read_cb($bev, $ctx) {
 $in = $bev->input; //$bev->getInput();
 
 printf("Received %zu bytes\n", $in->length);
 printf("----- data ----\n");
 printf("%ld:\t%s\n", (int) $in->length, $in->pullup(-1));
 
 $bev->writeBuffer($in);
 }
 
 // This callback is invoked when some even occurs on the event listener,
 // e.g. connection closed, or an error occured
 function ssl_event_cb($bev, $events, $ctx) {
 if ($events & EventBufferEvent::ERROR) {
 // Fetch errors from the SSL error stack
 while ($err = $bev->sslError()) {
 fprintf(STDERR, "Bufferevent error %s.\n", $err);
 }
 }
 
 if ($events & (EventBufferEvent::EOF | EventBufferEvent::ERROR)) {
 $bev->free();
 }
 }
 
 // This callback is invoked when a client accepts new connection
 function ssl_accept_cb($listener, $fd, $address, $ctx) {
 // We got a new connection! Set up a bufferevent for it.
 $this->bev = EventBufferEvent::sslSocket($this->base, $fd, $this->ctx,
 EventBufferEvent::SSL_ACCEPTING, EventBufferEvent::OPT_CLOSE_ON_FREE);
 
 if (!$this->bev) {
 echo "Failed creating ssl buffer\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);
 }
 
 // This callback is invoked when we failed to setup new connection for a client
 function accept_error_cb($listener, $ctx) {
 fprintf(STDERR, "Got an error %d (%s) on the listener. "
 ."Shutting down.\n",
 EventUtil::getLastSocketErrno(),
 EventUtil::getLastSocketError());
 
 $this->base->exit(NULL);
 }
 
 // Initialize SSL structures, create an EventSslContext
 // Optionally create self-signed certificates
 function init_ssl() {
 // We *must* have entropy. Otherwise there's no point to crypto.
 if (!EventUtil::sslRandPoll()) {
 exit("EventUtil::sslRandPoll failed\n");
 }
 
 $local_cert = __DIR__."/cert.pem";
 $local_pk   = __DIR__."/privkey.pem";
 
 if (!file_exists($local_cert) || !file_exists($local_pk)) {
 echo "Couldn't read $local_cert or $local_pk file.  To generate a key\n",
 "and self-signed certificate, run:\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;
 }
 }
 
 // Allow to override the port
 $port = 9999;
 if ($argc > 1) {
 $port = (int) $argv[1];
 }
 if ($port <= 0 || $port > 65535) {
 exit("Invalid port\n");
 }
 
 
 $l = new MySslEchoServer($port);
 $l->dispatch();
 ?>
 
  Example #5 Signal handler 
<?php/*
 Launch it in a terminal window:
 
 $ php examples/signal.php
 
 In another terminal window find out the pid and send SIGTERM, e.g.:
 
 $ 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
 
 At the first terminal window you should catch the following:
 
 Caught signal 15
 */
 class MyEventSignal {
 private $base;
 
 function __construct($base) {
 $this->base = $base;
 }
 
 function eventSighandler($no, $c) {
 echo "Caught 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);
 ?>
 
  Example #6 Use libevent's loop to process requests of `eio' extension 
<?php// Callback for eio_nop()
 function my_nop_cb($d, $r) {
 echo "step 6\n";
 }
 
 $dir = "/tmp/abc-eio-temp";
 if (file_exists($dir)) {
 rmdir($dir);
 }
 
 echo "step 1\n";
 
 $base = new EventBase();
 
 echo "step 2\n";
 
 eio_init();
 
 eio_mkdir($dir, 0750, EIO_PRI_DEFAULT, "my_nop_cb");
 
 $event = new Event($base, eio_get_event_stream(),
 Event::READ | Event::PERSIST, function ($fd, $events, $base) {
 echo "step 5\n";
 
 while (eio_nreqs()) {
 eio_poll();
 }
 
 $base->stop();
 }, $base);
 
 echo "step 3\n";
 
 $event->add();
 
 echo "step 4\n";
 
 $base->dispatch();
 
 echo "Done\n";
 ?>
 
  Example #7 Miscellaneous 
<?php/* {{{ Config & supported stuff */
 echo "Supported methods:\n";
 foreach (Event::getSupportedMethods() as $m) {
 echo $m, PHP_EOL;
 }
 
 // Avoiding "select" method
 $cfg = new EventConfig();
 if ($cfg->avoidMethod("select")) {
 echo "`select' method avoided\n";
 }
 
 // Create event_base associated with the config
 $base = new EventBase($cfg);
 echo "Event method used: ", $base->getMethod(), PHP_EOL;
 
 echo "Features:\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");
 
 // Require FDS feature
 if ($cfg->requireFeatures(EventConfig::FEATURE_FDS)) {
 echo "FDS feature is now requried\n";
 
 $base = new EventBase($cfg);
 ($base->getFeatures() & EventConfig::FEATURE_FDS)
 and print("FDS - arbitrary file descriptor types, and not just sockets\n");
 }
 /* }}} */
 
 /* {{{ Base */
 $base = new EventBase();
 $event = new Event($base, STDIN, Event::READ | Event::PERSIST, function ($fd, $events, $arg) {
 static $max_iterations = 0;
 
 if (++$max_iterations >= 5) {
 /* exit after 5 iterations with timeout of 2.33 seconds */
 echo "Stopping...\n";
 $arg[0]->exit(2.33);
 }
 
 echo fgets($fd);
 }, array (&$base));
 
 $event->add();
 $base->loop();
 /* Base }}} */
 ?>
 
  Example #8 Simple HTTP server 
<?php/*
 * Simple HTTP server.
 *
 * To test it:
 * 1) Run it on a port of your choice, e.g.:
 * $ php examples/http.php 8010
 * 2) In another terminal connect to some address on this port
 * and make GET or POST request(others are turned off here), e.g.:
 * $ nc -t 127.0.0.1 8010
 * POST /about HTTP/1.0
 * Content-Type: text/plain
 * Content-Length: 4
 * Connection: close
 * (press Enter)
 *
 * It will output
 * 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)
 *
 * It will output:
 * 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
 *
 * It will output:
 * HTTP/1.0 200 OK
 * Content-Type: text/html; charset=ISO-8859-1
 * Connection: close
 *
 * 3) See what the server outputs on the previous terminal window.
 */
 
 function _http_dump($req, $data) {
 static $counter      = 0;
 static $max_requests = 2;
 
 if (++$counter >= $max_requests)  {
 echo "Counter reached max requests $max_requests. Exiting\n";
 exit();
 }
 
 echo __METHOD__, " called\n";
 echo "request:"; var_dump($req);
 echo "data:"; var_dump($data);
 
 echo "\n===== DUMP =====\n";
 echo "Command:", $req->getCommand(), PHP_EOL;
 echo "URI:", $req->getUri(), PHP_EOL;
 echo "Input headers:"; var_dump($req->getInputHeaders());
 echo "Output headers:"; var_dump($req->getOutputHeaders());
 
 echo "\n >> Sending reply ...";
 $req->sendReply(200, "OK");
 echo "OK\n";
 
 echo "\n >> Reading input buffer ...\n";
 $buf = $req->getInputBuffer();
 while ($s = $buf->readLine(EventBuffer::EOL_ANY)) {
 echo $s, PHP_EOL;
 }
 echo "No more data in the buffer\n";
 }
 
 function _http_about($req) {
 echo __METHOD__, PHP_EOL;
 echo "URI: ", $req->getUri(), PHP_EOL;
 echo "\n >> Sending reply ...";
 $req->sendReply(200, "OK");
 echo "OK\n";
 }
 
 function _http_default($req, $data) {
 echo __METHOD__, PHP_EOL;
 echo "URI: ", $req->getUri(), PHP_EOL;
 echo "\n >> Sending reply ...";
 $req->sendReply(200, "OK");
 echo "OK\n";
 }
 
 $port = 8010;
 if ($argc > 1) {
 $port = (int) $argv[1];
 }
 if ($port <= 0 || $port > 65535) {
 exit("Invalid port");
 }
 
 $base = new EventBase();
 $http = new EventHttp($base);
 $http->setAllowedMethods(EventHttpRequest::CMD_GET | EventHttpRequest::CMD_POST);
 
 $http->setCallback("/dump", "_http_dump", array(4, 8));
 $http->setCallback("/about", "_http_about");
 $http->setDefaultCallback("_http_default", "custom data value");
 
 $http->bind("0.0.0.0", 8010);
 $base->loop();
 ?>
 The above example will output
something similar to:
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
 
  Example #9 Simple HTTPS server 
<?php/*
 * Simple HTTPS server.
 *
 * 1) Run the server: `php examples/https.php 9999`
 * 2) Test it: `php examples/ssl-connection.php 9999`
 */
 
 function _http_dump($req, $data) {
 static $counter      = 0;
 static $max_requests = 200;
 
 if (++$counter >= $max_requests)  {
 echo "Counter reached max requests $max_requests. Exiting\n";
 exit();
 }
 
 echo __METHOD__, " called\n";
 echo "request:"; var_dump($req);
 echo "data:"; var_dump($data);
 
 echo "\n===== DUMP =====\n";
 echo "Command:", $req->getCommand(), PHP_EOL;
 echo "URI:", $req->getUri(), PHP_EOL;
 echo "Input headers:"; var_dump($req->getInputHeaders());
 echo "Output headers:"; var_dump($req->getOutputHeaders());
 
 echo "\n >> Sending reply ...";
 $req->sendReply(200, "OK");
 echo "OK\n";
 
 $buf = $req->getInputBuffer();
 echo "\n >> Reading input buffer (", $buf->length, ") ...\n";
 while ($s = $buf->read(1024)) {
 echo $s;
 }
 echo "\nNo more data in the buffer\n";
 }
 
 function _http_about($req) {
 echo __METHOD__, PHP_EOL;
 echo "URI: ", $req->getUri(), PHP_EOL;
 echo "\n >> Sending reply ...";
 $req->sendReply(200, "OK");
 echo "OK\n";
 }
 
 function _http_default($req, $data) {
 echo __METHOD__, PHP_EOL;
 echo "URI: ", $req->getUri(), PHP_EOL;
 echo "\n >> Sending reply ...";
 $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 <= 0 || $port > 65535) {
 exit("Invalid port");
 }
 $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(4, 8));
 $http->setCallback("/about", "_http_about");
 $http->setCallback("/err400", "_http_400");
 $http->setDefaultCallback("_http_default", "custom data value");
 
 $http->bind($ip, $port);
 $base->dispatch();
 
  Example #10 OpenSSL connection 
<?php/*
 * Sample OpenSSL client.
 *
 * Usage:
 * 1) Launch a server, e.g.:
 * $ php examples/https.php 9999
 *
 * 2) Launch the client in another terminal:
 * $ php examples/ssl-connection.php 9999
 */
 
 function _request_handler($req, $base) {
 echo __FUNCTION__, PHP_EOL;
 
 if (is_null($req)) {
 echo "Timed out\n";
 } else {
 $response_code = $req->getResponseCode();
 
 if ($response_code == 0) {
 echo "Connection refused\n";
 } elseif ($response_code != 200) {
 echo "Unexpected response: $response_code\n";
 } else {
 echo "Success: $response_code\n";
 $buf = $req->getInputBuffer();
 echo "Body:\n";
 while ($s = $buf->readLine(EventBuffer::EOL_ANY)) {
 echo $s, PHP_EOL;
 }
 }
 }
 
 $base->exit(NULL);
 }
 
 function _init_ssl() {
 $ctx = new EventSslContext(EventSslContext::SSLv3_CLIENT_METHOD, array ());
 
 return $ctx;
 }
 
 
 // Allow to override the port
 $port = 9999;
 if ($argc > 1) {
 $port = (int) $argv[1];
 }
 if ($port <= 0 || $port > 65535) {
 exit("Invalid port\n");
 }
 $host = '127.0.0.1';
 
 $ctx = _init_ssl();
 if (!$ctx) {
 trigger_error("Failed creating SSL context", E_USER_ERROR);
 }
 
 $base = new EventBase();
 if (!$base) {
 trigger_error("Failed to initialize event base", E_USER_ERROR);
 }
 
 $conn = new EventHttpConnection($base, NULL, $host, $port, $ctx);
 $conn->setTimeout(50);
 
 $req = new EventHttpRequest("_request_handler", $base);
 $req->addHeader("Host", $host, EventHttpRequest::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($req, EventHttpRequest::CMD_POST, "/dump");
 
 $base->dispatch();
 echo "END\n";
 ?>
 
  Example #11 
   EventHttpConnection::makeRequest example 
<?phpfunction _request_handler($req, $base) {
 echo __FUNCTION__, PHP_EOL;
 
 if (is_null($req)) {
 echo "Timed out\n";
 } else {
 $response_code = $req->getResponseCode();
 
 if ($response_code == 0) {
 echo "Connection refused\n";
 } elseif ($response_code != 200) {
 echo "Unexpected response: $response_code\n";
 } else {
 echo "Success: $response_code\n";
 $buf = $req->getInputBuffer();
 echo "Body:\n";
 while ($s = $buf->readLine(EventBuffer::EOL_ANY)) {
 echo $s, PHP_EOL;
 }
 }
 }
 
 $base->exit(NULL);
 }
 
 $address = "127.0.0.1";
 $port = 80;
 
 $base = new EventBase();
 $conn = new EventHttpConnection($base, NULL, $address, $port);
 $conn->setTimeout(5);
 $req = new EventHttpRequest("_request_handler", $base);
 
 $req->addHeader("Host", $address, EventHttpRequest::OUTPUT_HEADER);
 $req->addHeader("Content-Length", "0", EventHttpRequest::OUTPUT_HEADER);
 $conn->makeRequest($req, EventHttpRequest::CMD_GET, "/index.cphp");
 
 $base->loop();
 ?>
 The above example will output
something similar to:
_request_handler
Success: 200
Body:
PHP, date:
2013-03-13T20:27:52+05:00
 
  Example #12 
   Connection listener based on a UNIX domain socket 
<?php/*
 * Simple echo server based on libevent's connection listener.
 *
 * Usage:
 * 1) In one terminal window run:
 *
 * $ php unix-domain-listener.php [path-to-socket]
 *
 * 2) In another terminal window open up connection
 * to the socket, e.g.:
 *
 * $ socat - GOPEN:/tmp/1.sock
 *
 * 3) Start typing. The server should repeat the input.
 */
 
 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, $fd, EventBufferEvent::OPT_CLOSE_ON_FREE);
 
 $this->bev->setCallbacks(array($this, "echoReadCallback"), NULL,
 array($this, "echoEventCallback"), NULL);
 
 if (!$this->bev->enable(Event::READ)) {
 echo "Failed to enable READ\n";
 return;
 }
 }
 
 public function echoReadCallback($bev, $ctx) {
 // Copy all the data from the input buffer to the output buffer
 $bev->output->addBuffer($bev->input);
 }
 
 public function echoEventCallback($bev, $events, $ctx) {
 if ($events & EventBufferEvent::ERROR) {
 echo "Error from 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("Couldn't create listener", E_USER_ERROR);
 }
 
 $this->listener->setErrorCallback(array($this, "accept_error_cb"));
 }
 
 public function dispatch() {
 $this->base->dispatch();
 }
 
 // This callback is invoked when there is data to read on $bev
 public function acceptConnCallback($listener, $fd, $address, $ctx) {
 // We got a new connection! Set up a bufferevent for it. */
 $base = $this->base;
 $this->conn[] = new MyListenerConnection($base, $fd);
 }
 
 public function accept_error_cb($listener, $ctx) {
 $base = $this->base;
 
 fprintf(STDERR, "Got an error %d (%s) on the listener. "
 ."Shutting down.\n",
 EventUtil::getLastSocketErrno(),
 EventUtil::getLastSocketError());
 
 $base->exit(NULL);
 }
 }
 
 if ($argc <= 1) {
 exit("Socket path is not provided\n");
 }
 $sock_path = $argv[1];
 
 $l = new MyListener($sock_path);
 $l->dispatch();
 ?>
 
  Example #13 Simple SMTP server 
<?php/*
 * Author: Andrew Rose <hello at andrewrose dot co dot uk>
 *
 * Usage:
 * 1) Prepare cert.pem certificate and privkey.pem private key files.
 * 2) Launch the server script
 * 3) Open TLS connection, e.g.:
 *      $ openssl s_client -connect localhost:25 -starttls smtp -crlf
 * 4) Start testing the commands listed in `cmd` method below.
 */
 
 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, // change to true with authentic cert
 EventSslContext::OPT_ALLOW_SELF_SIGNED => true // change to false with authentic cert
 ]);
 
 $this->base = new EventBase();
 if (!$this->base) {
 exit("Couldn't open event base\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("Couldn't create listener\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 "Failed creating 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, "Got an error %d (%s) on the listener. Shutting down.\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")
 {
 // remove the trailing \r\n
 $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 'unknown command: '.$line."\n";
 break;
 }
 }
 }
 
 new Handler();
 |