在没有cron作业纯PHP的情况下调度任务

时间:2019-05-27 21:36:05

标签: php sleep schedule

我创建了一个模仿CRON作业的php脚本。第一个访问该网站的用户将触发一个变成计时器的请求。在计时器中,我检查当前时间是否是我需要执行某件事的时间。如果不是该时间,它将休眠60秒并再次检查。这工作得很好,但是在我执行第一个请求之后,sleep()函数将阻止以后的所有请求。仅在清除浏览器历史记录或进入隐身模式后,网站才能再次运行且计时器仍处于活动状态(因此一切正常)。但是我想在php代码(或javascript)中动态地做到这一点。

我尝试成功的以下两件事:

  • 使用javascript清除会话cookie并刷新(document.cookie = ""
  • 使用session_write_close()功能

How can I stop PHP sleep() affecting my whole PHP code?

在这篇文章中,他们提到sleep()方法使整个会话休眠。这就是为什么清除浏览器历史记录的原因。

所以我的问题是:是否可以动态地转储用户会话?

下面是我的代码:

<?php
session_start();

if(!isRequestActive())
{
    startTimer();
}

function isRequestActive()
{
    $file = 'time.txt';
    $now = new DateTime('now');
    if(!is_file($file)){

        file_put_contents($file, $now->format('Y-m-d H:i:s'));
        return false;
    }

    $contents = file_get_contents($file);
    $date = DateTime::createFromFormat('Y-m-d H:i:s',$contents);
    $difference = $now->getTimestamp() - $date->getTimestamp();

    if($difference > 60)
    {
        return false;
    }

    return true;
}

function startTimer()
{
    ini_set('max_execution_time', 99999999);
    ignore_user_abort(true);
    session_write_close();
    while(true)
    {
        $now = new DateTime('now');
        file_put_contents("time.txt", $now->format('Y-m-d H:i:s'));
        if($now->format('D H:i') == 'Mon 23:05')
        {
            // Here i can do my scheduled event
        }
        sleep(60);
    }
}

我知道还有许多其他选项可用于安排任务,但就我而言,我无法使用其中任何一个。我问了一个与此相关的问题,没有结果: PHP scheduling a task on webhosting without SSH/Console

对不起,我的英语不好,这不是我的母语。

1 个答案:

答案 0 :(得分:-1)

感谢Arleigh Hix的建议,我找到了解决方案。对于不想使用CRON作业或具有与我相同的限制的人,或者如果您只是不想在下面获得额外的依赖,则是纯PHP任务的代码:

<?php
session_start();

if(!isRequestActive())
{
    startTimer();
}

function isRequestActive()
{
    $file = 'time.txt';
    $now = new DateTime('now');
    if(!is_file($file)){

        file_put_contents($file, $now->format('Y-m-d H:i:s'));
        return false;
    }

    $contents = file_get_contents($file);
    $date = DateTime::createFromFormat('Y-m-d H:i:s',$contents);
    $difference = $now->getTimestamp() - $date->getTimestamp();

    if($difference > 60)
    {
        return false;
    }

    return true;
}

function startTimer()
{
    ini_set('max_execution_time', 99999999);
    session_destroy();
    ignore_user_abort(true);
    session_write_close();
    while(true)
    {
        $now = new DateTime('now');
        file_put_contents("time.txt", $now->format('Y-m-d H:i:s'));
        if($now->format('D H:i') == 'Tue 01:01')// Set the time you want to execute a task
        {
            // Code that you want to execute on said time
        }
        ob_start();
        echo "<script>document.location.href = document.location.href</script>";
        ob_end_flush();
        ob_flush();
        flush();
        sleep(60);
    }
}

请注意,此解决方案需要您具有写入文件的权限。如果需要,可以将其替换为数据库连接。但是我认为它比读取一个文件要慢(因为该文件在每次请求时都会被检查)。