当前位置: 首页 > 工具软件 > pecl-ev > 使用案例 >

PHP扩展ev示例翻译

赫连俊悟
2023-12-01
php的libev扩展
提供了一些类似nodejs异步调用的方式,
用途很多,如文件状态监视,流阻塞等待异步
pecl库的,默认不安装,需要自己在pecl下弄个过来
php manual地址:http://www.php.net/manual/zh/ev.examples.php
如果不知道libev是啥可以看这个http://dirlt.com/libev.html
这里罗列下具体手册内的代码,只翻译了关键注释
刚才由于对代码没有整理,竟然被过滤掉了……不能发html pre代码的博客编辑器好凄惨

// 创建一个定时器,2秒后启动,不循环只执行一次
$w1 new EvTimer(20function () {
    echo 
"2 seconds elapsed\n";
});

// 创建一个定时器,2秒后启动,1秒执行一次
// 直到碰到指定代码停止
$w2 new EvTimer(21function ($w{
    echo 
"is called every second, is launched after seconds\n";
    echo 
"iteration "Ev::iteration(), PHP_EOL;

    
// 执行第五次停止
    
Ev::iteration() == and $w->stop();
    
// Stop the watcher if further calls cause more than 10 iterations
    
Ev::iteration() >= 10 and $w->stop();
});

//创建计时器,未激活,需要代码激活
$w_stopped EvTimer::createStopped(105function($w{
    echo 
"Callback of timer created as stopped\n";

    
// 事件产生两次后停止定时器
    
Ev::iteration() >= and $w->stop();
});

// 循环直到所有都关闭
Ev::run();

// 启动并检查是否开始工作
$w_stopped->start();
echo 
"Run single iteration\n";
Ev::run(Ev::RUN_ONCE);

echo 
"重启定时器,并尝试继续处理相同事件,但是这次是非阻塞的方式\n";
$w2->again();
Ev::run(Ev::RUN_NOWAIT);

$w new EvTimer(100function() {});
echo 
"阻塞方式运行\n";
Ev::run();
echo 
"END\n";


========================
// 等待一直到STDIN准备好并可读
$w new EvIo(STDINEv::READfunction ($watcher$revents{
    echo 
"STDIN is readable\n";
});

Ev::run(Ev::RUN_ONCE);


========================
非阻塞
$e_nonblocking array (11115);

// 获取www服务服务端口
$service_port getservbyname('www''tcp');

// 获取域名对应ip
$address gethostbyname('google.co.uk');

//创建socket通讯
$socket socket_create(AF_INETSOCK_STREAMSOL_TCP);
if (
$socket === FALSE{
    echo 
"socket_create() failed: reason: "
        
.socket_strerror(socket_last_error()) "\n";
}

// 表示非阻塞方式
socket_set_nonblock($socket);

// 如果在使用中超时自动关闭,这里用了evtimer
$timeout_watcher new EvTimer(10.00.function () use ($socket{
    
socket_close($socket);
    
Ev::stop(Ev::BREAK_ALL);
});

// 当socket可用后,进行发送接收操作
$write_watcher new EvIo($socketEv::WRITEfunction ($w)
    use (
$socket$timeout_watcher$e_nonblocking)
{
    
// 超时timer停用
    
$timeout_watcher->stop();
    
// 停用evio监视
    
$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$instrlen($in))) {
        
trigger_error("Failed writing $in to socket"E_USER_ERROR);
    }

    
$read_watcher new EvIo($socketEv::READfunction ($w$re)
        use (
$socket$e_nonblocking)
    {
        
// 非阻塞情况下从socket读取20字节数据
        
$ret socket_recv($socket$out20MSG_DONTWAIT);

        if (
$ret{
            echo 
$out;
        elseif (
$ret === 0{
            
// 读取完毕
            
$w->stop();
            
socket_close($socket);
            return;
        }

        
// socket通讯错误
        
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();


===========================
信号处理,当收到控制信号时自动启动
$w new EvSignal(SIGTERMfunction ($watcher{
    echo 
"SIGTERM received\n";
    
$watcher->stop();
});

Ev::run();


===========================
// 指定文件修改监视当监视文件出现变化,则触发,每8秒检查一次
$w new EvStat("/var/log/messages"8function ($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();


============================
进程状态监视
$pid pcntl_fork();

if (
$pid == -1{
    
fprintf(STDERR"pcntl_fork failed\n");
elseif (
$pid{
    
$w new EvChild($pidFALSEfunction ($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);
}

 类似资料: