php 定时器

本文介绍了如何在PHP中实现定时任务,包括使用sock跳转和通过数据库判断的方法,避免了文件操作的繁琐。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >



//每晚11.55执行   启动apache 以后 访问首页开启 需要晚上11.55开启
// 启动apache app 目录下添加 cron-run 访问首页 启动  定时任务第一次执行的时间是每晚的11.55
//如果不存在cron-switch这个文件,就停止执行,这是一个开关的作用
function dowhile()
{
    //11.55维护 5分钟 禁止用户进行金额操作 购物 充值 提现  session 判断 cal_bal 前 session+  cal_bal后 session-
    ignore_user_abort(true);
    set_time_limit(0);
    date_default_timezone_set('PRC'); // 切换到中国的时间
    $run_time = strtotime(date("Y-m-d").' 23:55:00');// 定时任务第一次执行的时间是每晚的11.55
    $interval = 3600 * 24; // 每24个小时执行一次
    // 在目录下存放一个cron-run文件,如果这个文件不存在,说明已经在执行过程中了,该任务就不能再激活,执行第二次,否则这个文件被多次访问的话,服务器就要崩溃掉了
    if (!file_exists(dirname(__FILE__) . '/cron-run')) exit();
    do {
        // 如果不存在cron-switch这个文件,就停止执行,这是一个开关的作用
        if (!file_exists(dirname(__FILE__) . '/cron-switch')) break;
        // 当前的运行时间,精确到0.0001秒
        $gmt_time = microtime(true);
        // 这里处理是为了确定还要等多久才开始第一次执行任务,$loop就是要等多久才执行的时间间隔
        $loop = isset($loop) && $loop ? $loop : $run_time - $gmt_time;
        $loop = $loop > 0 ? $loop : 0;
        // 如果循环的间隔为零,则停止
        if (!$loop) break;
        sleep($loop);
        // 分钱
        \think\Session::set('dowhile', true);
        cal_bal();
        \think\Session::delete('dowhile');
        // 这里就是通过删除cron-run来告诉程序,这个定时任务已经在执行过程中,不能再执行一个新的同样的任务
        @unlink(dirname(__FILE__) . '/cron-run');
        $loop = $interval;
    } while (true);
}


// 远程请求(不获取内容)函数,下面可以反复使用
function _sock($url)
{
    $host = parse_url($url, PHP_URL_HOST);
    $port = parse_url($url, PHP_URL_PORT);
    $port = $port ? $port : 80;
    $scheme = parse_url($url, PHP_URL_SCHEME);
    $path = parse_url($url, PHP_URL_PATH);
    $query = parse_url($url, PHP_URL_QUERY);
    if ($query) $path .= '?' . $query;
    if ($scheme == 'https') {
        $host = 'ssl://' . $host;
    }

    $fp = fsockopen($host, $port, $error_code, $error_msg, 1);
    if (!$fp) {
        return array('error_code' => $error_code, 'error_msg' => $error_msg);
    } else {
        stream_set_blocking($fp, true);//开启了手册上说的非阻塞模式
        stream_set_timeout($fp, 1);//设置超时
        $header = "GET $path HTTP/1.1\r\n";
        $header .= "Host: $host\r\n";
        $header .= "Connection: close\r\n\r\n";//长连接关闭
        fwrite($fp, $header);
        usleep(1000); // 这一句也是关键,如果没有这延时,可能在nginx服务器上就无法执行成功
        fclose($fp);
        return array('error_code' => 0);
    }
}

 public function dowhile()
    {
        $file = str_replace('\\', '/', strstr(dirname(__FILE__), 'newadmin\controller', true));
        touch($file . "/cron-run");
         _sock(request()->domain() . '/home/index/dowhile');
        ajaxReturn(1, '开启成功', '');
    }
 public function dowhile()
    {
        dowhile();
    }

    public function fen()
    {
        _sock(request()->domain() . '/home/index/dowhile');
    }

使用 sock 跳转方法 按钮点击dowhile 跳转

//每日返现
function cal_bal()
{
    $bal_data = db('user')->field('uid,total_bal,drwa_bal,fuxin_dis,fenhong')->select();
    foreach ($bal_data as $key => &$v) {
        if ($v['total_bal'] < 100) continue;
        $total_bal = ($num = ((int)(ceil($v['total_bal'] / 10000)))) ? $num * 100 : 100;
        $fenhong = $total_bal * 0.9;
        $v['fenhong'] += $fenhong;
        $v['drwa_bal'] += $fenhong;
        $v['fuxin_dis'] += ($fuxinq = $total_bal * 0.1);
        $v['total_bal'] = $v['total_bal'] - $total_bal;
        $res = Db::name('user')->update($v);
        if ($res) {
            fen_log($v['uid'], 0, $fenhong, 1);
            fen_log($v['uid'], 3, $fuxinq, 1);
        } else {
            fen_log($v['uid'], 0, $fenhong, 0);
            fen_log($v['uid'], 3, $fuxinq, 0);
        }
    }
}

用文件麻烦 可以在数据库插入一条数据 进行判断’
版本二’

   //分红
    function dowhile()
    {
        ignore_user_abort(true);
        set_time_limit(0);
        date_default_timezone_set('PRC'); // 切换到中国的时间
        $run_time = strtotime(date("Y-m-d") . ' 23:55:00');
        $interval = 3600 * 24; // 每24个小时执行一次
        do {
            // 当前的运行时间,精确到0.0001秒
            $gmt_time = microtime(true);
            // 这里处理是为了确定还要等多久才开始第一次执行任务,$loop就是要等多久才执行的时间间隔
            $loop = isset($loop) && $loop ? $loop : $run_time - $gmt_time;
            $loop = $loop > 0 ? $loop : 0;
            // 如果循环的间隔为零,则停止
            if (!$loop) break;
            sleep($loop);
            $old_time = Db::name('date')->where('id', 1)->value('time');
            if (date("Y-m-d") === $old_time) break;
            \think\Session::set('dowhile', true);
            $this->cal_bal();
            \think\Session::delete('dowhile');
            Db::name('date')->where('id', 1)->update(['time' => date('Y-m-d')]);
            $loop = $interval;
        } while (true);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值