Exemples
Exemple #1 Simple timers
<?php // Create and start timer firing after 2 seconds $w1 = new EvTimer(2, 0, function () { echo "2 seconds elapsed\n"; }); // Create and launch timer firing after 2 seconds repeating each second // until we manually stop it $w2 = new EvTimer(2, 1, function ($w) { echo "is called every second, is launched after 2 seconds\n"; echo "iteration = ", Ev::iteration(), PHP_EOL; // Stop the watcher after 5 iterations Ev::iteration() == 5 and $w->stop(); // Stop the watcher if further calls cause more than 10 iterations Ev::iteration() >= 10 and $w->stop(); }); // Create stopped timer. It will be inactive until we start it ourselves $w_stopped = EvTimer::createStopped(10, 5, function($w) { echo "Callback of a timer created as stopped\n"; // Stop the watcher after 2 iterations Ev::iteration() >= 2 and $w->stop(); }); // Loop until Ev::stop() is called or all of watchers stop Ev::run(); // Start and look if it works $w_stopped->start(); echo "Run single iteration\n"; Ev::run(Ev::RUN_ONCE); echo "Restart the second watcher and try to handle the same events, but don't block\n"; $w2->again(); Ev::run(Ev::RUN_NOWAIT); $w = new EvTimer(10, 0, function() {}); echo "Running a blocking loop\n"; Ev::run(); echo "END\n"; ?>
<?php
$w = new EvPeriodic(0., 10.5, NULL, function ($w, $revents) {
echo time(), PHP_EOL;
});
Ev::run();
?>
Exemple #3 Periodic timer. Use reschedule callback
Exemple #4 Periodic timer. Tick every 10.5 seconds starting at now
Exemple #5 Wait until STDIN is readable
<?php // Wait until STDIN is readable $w = new EvIo(STDIN, Ev::READ, function ($watcher, $revents) { echo "STDIN is readable\n"; }); Ev::run(Ev::RUN_ONCE); ?>
Exemple #6 Use some async I/O to access a socket
<?php /* Use some async I/O to access a socket */ // `sockets' extension still logs warnings // for EINPROGRESS, EAGAIN/EWOULDBLOCK etc. error_reporting(E_ERROR); $e_nonblocking = array (/*EAGAIN or EWOULDBLOCK*/11, /*EINPROGRESS*/115); // Get the port for the WWW service $service_port = getservbyname('www', 'tcp'); // Get the IP address for the target host $address = gethostbyname('google.co.uk'); // Create a TCP/IP socket $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); if ($socket === FALSE) { echo "socket_create() failed: reason: " .socket_strerror(socket_last_error()) . "\n"; } // Set O_NONBLOCK flag socket_set_nonblock($socket); // Abort on timeout $timeout_watcher = new EvTimer(10.0, 0., function () use ($socket) { socket_close($socket); Ev::stop(Ev::BREAK_ALL); }); // Make HEAD request when the socket is writable $write_watcher = new EvIo($socket, Ev::WRITE, function ($w) use ($socket, $timeout_watcher, $e_nonblocking) { // Stop timeout watcher $timeout_watcher->stop(); // Stop write watcher $w->stop(); $in = "HEAD / HTTP/1.1\r\n"; $in .= "Host: google.co.uk\r\n"; $in .= "Connection: Close\r\n\r\n"; if (!socket_write($socket, $in, strlen($in))) { trigger_error("Failed writing $in to socket", E_USER_ERROR); } $read_watcher = new EvIo($socket, Ev::READ, function ($w, $re) use ($socket, $e_nonblocking) { // Socket is readable. recv() 20 bytes using non-blocking mode $ret = socket_recv($socket, $out, 20, MSG_DONTWAIT); if ($ret) { echo $out; } elseif ($ret === 0) { // All read $w->stop(); socket_close($socket); return; } // Caught EINPROGRESS, EAGAIN, or EWOULDBLOCK if (in_array(socket_last_error(), $e_nonblocking)) { return; } $w->stop(); socket_close($socket); }); Ev::run(); }); $result = socket_connect($socket, $address, $service_port); Ev::run(); ?>
<?php /* * Try to get an embeddable event loop and embed it into the default event loop. * If it is impossible, use the default * loop. The default loop is stored in $loop_hi, while the embeddable loop is * stored in $loop_lo(which is $loop_hi in the case no embeddable loop can be * used). * * Sample translated to PHP * http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod#Examples_CONTENT-9 */ $loop_hi = EvLoop::defaultLoop(); $loop_lo = NULL; $embed = NULL; /* * See if there is a chance of getting one that works * (flags' value of 0 means autodetection) */ $loop_lo = Ev::embeddableBackends() & Ev::recommendedBackends() ? new EvLoop(Ev::embeddableBackends() & Ev::recommendedBackends()) : 0; if ($loop_lo) { $embed = new EvEmbed($loop_lo, function () {}); } else { $loop_lo = $loop_hi; } ?>
Exemple #8 Embedding loop created with kqueue backend into the default loop
<?php /* * Check if kqueue is available but not recommended and create a kqueue backend * for use with sockets (which usually work with any kqueue implementation). * Store the kqueue/socket-only event loop in loop_socket. (One might optionally * use EVFLAG_NOENV, too) * * Example borrowed from * http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod#Examples_CONTENT-9 */ $loop = EvLoop::defaultLoop(); $socket_loop = NULL; $embed = NULL; if (Ev::supportedBackends() & ~Ev::recommendedBackends() & Ev::BACKEND_KQUEUE) { if (($socket_loop = new EvLoop(Ev::BACKEND_KQUEUE))) { $embed = new EvEmbed($loop); } } if (!$socket_loop) { $socket_loop = $loop; } // Now use $socket_loop for all sockets, and $loop for anything else ?>
Exemple #9 Handle SIGTERM signal
<?php $w = new EvSignal(SIGTERM, function ($watcher) { echo "SIGTERM received\n"; $watcher->stop(); }); Ev::run(); ?>
Exemple #10 Monitor changes of /var/log/messages
<?php // Use 10 second update interval. $w = new EvStat("/var/log/messages", 8, function ($w) { echo "/var/log/messages changed\n"; $attr = $w->attr(); if ($attr['nlink']) { printf("Current size: %ld\n", $attr['size']); printf("Current atime: %ld\n", $attr['atime']); printf("Current mtime: %ld\n", $attr['mtime']); } else { fprintf(STDERR, "`messages` file is not there!"); $w->stop(); } }); Ev::run(); ?>
Exemple #11 Monotor changes of /var/log/messages. Avoid missing updates by means of one second delay
<?php
$timer = EvTimer::createStopped(0., 1.02, function ($w) {
$w->stop();
$stat = $w->data;
// 1 second after the most recent change of the file
printf("Current size: %ld\n", $stat->attr()['size']);
});
$stat = new EvStat("/var/log/messages", 0., function () use ($timer) {
// Reset timer watcher
$timer->again();
});
$timer->data = $stat;
Ev::run();
?>
Exemple #12 Process status changes
<?php $pid = pcntl_fork(); if ($pid == -1) { fprintf(STDERR, "pcntl_fork failed\n"); } elseif ($pid) { $w = new EvChild($pid, FALSE, function ($w, $revents) { $w->stop(); printf("Process %d exited with status %d\n", $w->rpid, $w->rstatus); }); Ev::run(); // Protect against Zombies pcntl_wait($status); } else { //Forked child exit(2); } ?>