使用循环运行 EvPeriodic

问题描述

我正在尝试运行 EvPeridoc 以定期(每 15 分钟,即 900 秒)将数据记录到文件中。

<?PHP
$tolog = '';
$w = new EvPeriodic(fmod(Ev::Now(),900),900,NULL,function($w,$revents)
{
    file_put_contents("log.txt",$tolog . PHP_EOL,FILE_APPEND | LOCK_EX);
});
Ev::run(Ev::RUN_NowAIT);
echo "Started periodic @ " . date("Y-m-d h:i:sa") . PHP_EOL;
for (;;) {
    $tolog = "Update @ " . date("Y-m-d h:i:sa");
}

周期从不触发,但应用程序进入 for 循环。 如果我将行 Ev::run(Ev::RUN_NowAIT); 更改为 Ev::run();,则脚本永远不会到达循环。

那么问题是我如何管理这段代码以能够每 15 分钟触发一次日志记录程序?

编辑: 只是为了澄清 - 此脚本末尾的无限循环生成要记录的数据(并将值分配给 $tolog globabl 变量)。我希望 EvPeriodic 每 15 分钟获取一次(全局)变量并将其附加到文件中。

解决方法

根据对问题的评论,不可能同时使用无限循环(在我的生产应用程序中是流式 http 循环)和 Evperiodic。我通过使用 IPC 解决了这个问题,最终不得不在单独的脚本中运行 EvPeriodic 代码。

主应用

<?php
$socket  = socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
socket_bind($socket,'127.0.0.1',15000);
socket_listen($socket);
socket_set_nonblock($socket);
$tolog= '';
for (;;){
        $tolog = "Update @ " . date("Y-m-d h:i:sa");
        if (($newc = socket_accept($socket)) !== false) {
                socket_write($newc,$tolog,strlen($tolog));
                socket_close($newc);
        }
}

带有 EvPeriodic 轮询主应用程序的“客户端”应用程序

<?php
$w = new EvPeriodic(fmod(Ev::now(),15),15,NULL,function($w,$revents){
        $sock = socket_create(AF_INET,SOL_TCP);
        socket_connect($sock,15000);
        $line = trim(socket_read($sock,1024));
        file_put_contents("/var/log/cohocompanies.log",$line . PHP_EOL,FILE_APPEND | LOCK_EX);
        socket_close($sock);
});
Ev::run();