php执行定时任务?

发布于 2022-09-05 02:54:42 字数 119 浏览 17 评论 0

用户添加定时任务后如
  每月30 号发工资
  订单到期未付款恢复
这种是如何做的?
直接在Linux 操作crontab 可以,
但是用户添加一个任务就加到 crontab 怎么实现?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

花期渐远 2022-09-12 02:54:43

关键词: shell_exec ,php 安全模式

shell_exec 解决你添加定时任务的问题 ,php 安全模式开启的时候是没法使用 shell_exec 函数的。

酒绊 2022-09-12 02:54:43

定时任务可以存储到MySQL或者文件里,然后用crontab 去跑mysql或文件

叹梦 2022-09-12 02:54:43

使用crontab,如:

0 0 30 * * 执行文件
傾城如夢未必闌珊 2022-09-12 02:54:43

可以参考 laravel任务调度 。即使不用 laravel,也可以参考 laravel任务调度 的实现思路, 其实原理很简单:

  1. 添加一个 crontab任务 ,每分钟执行一次某个 php 脚本。
  2. 脚本里获取到所有任务,遍历任务,根据该任务的执行规则,判断该任务是否需要执行,需要执行的话执行完更新当前执行时间以便下一次执行的时候判断。
  3. 继续完善的话就是防止重复执行,给任务添加执行状态之类的属性。
  4. more ...

用 crontab 每分钟执行一遍实现的调度的时间精度只有一分钟,想要更小的精度可以考虑用 swooleworkermanreactphp 之类的库来实现,至于任务执行规则可以参考 linux 自带的 crontab 规则,也就是 * * * * * 这样的。
又或者直接用现成的 php 任务调度框架。

南烟 2022-09-12 02:54:43

mysql 存储过程也可以跑定时任务

看海 2022-09-12 02:54:43

用独立的定时任务中间件管理, 用户定时任务不适合放到crontab中

野却迷人 2022-09-12 02:54:43

我引用一下Naist
首先你要会使用crontab,没错,不会用就自己百度了,这里不做回答,可以写一篇博客了。
然后在命令行

crontab -e

了之后

0 0 30 * * php 需要定期执行的php脚本位置
青柠芒果 2022-09-12 02:54:43

有可能不是crontab,我之前用node.js写过一个用户可以自己定时的WebSocket,在后台挂起。当用户向这个WebSocket发送请求时,把定时的时间记录到一个缓存文件中(JSON),然后设置node.js自己的定时器。

如果这个WebSocket服务挂掉了的话,只要重新启动这个后台脚本,脚本会通过缓存的JSON里记录的时间,重新设定计划任务。这里我可以放一些代码,核心的代码被省略,另外加了点注释供参考

'use strict';
// 一些NodeJS包
const WebSocket = require('ws');
const path = require('path');
const crontab = require('node-crontab');
const spawn = require('cross-spawn');
const fsExtra = require('fs-extra');
const objectValues = require('object-values');

// 省略了一些配置

const wss = new WebSocket.Server({port: 8080}); // 创建WebSocket服务

let ScheduleList = {}; // 这个为存储时间的JS对象
let JobList      = {}; // 这个为存储定时任务ID的JS对象,如果要取消任务,就通过这个来查找定时任务ID

// 省略了日志方法

// 故障后重启载入任务时间的方法
const loadJobs = () => {
    let jobsCache = path.resolve(__dirname, './config/scheduler.jobs');

    if(fsExtra.pathExistsSync(jobsCache)) {
        ScheduleList = fsExtra.readJsonSync(jobsCache, {throw: false}) || {};
    }
};
// 用户传入时间时将任务时间对象ScheduleList重写到文件的方法
const saveJobs = () => {
    let jobsCache = path.resolve(__dirname, './config/scheduler.jobs');
    fsExtra.outputJsonSync(jobsCache, ScheduleList);
};
// 根据ScheduleList重新创建计划任务的方法
const rerunJobs = () => {
    for(let jobScheduleId in ScheduleList) {
        let hour   = ScheduleList[jobScheduleId].hour || 0;
        let minute = ScheduleList[jobScheduleId].minute || 0;

        let jobId = crontab.scheduleJob(`${minute} ${hour} * * *`, () => {
            // 此处省略了任务创建的具体操作,用的cross-spawn包
        });

        JobList[id] = jobId;
    }
};

loadJobs(); // 启动时载入时间
rerunJobs(); // 根据时间重新创建计划任务

wss.on('connection', ws => {
    ws.on('message', message => {
        // 省略了传入数据的解析

        // 如果任务存在,先删除任务
        if(JobList[id]) {
            crontab.cancelJob(JobList[id]);
            delete ScheduleList[id];
            delete JobList[id];
        }

        // 重新添加任务
        let jobId = crontab.scheduleJob(`${minute} ${hour} * * *`, () => {
            // 同rerunJobs()里的创建操作,省略细节
        });

        ScheduleList[id] = {id: id, hour: hour, minute: minute};
        JobList[id]      = jobId;

        saveJobs(); // 保存任务计划时间

        ws.send(JSON.stringify(response(null, {message: '应用成功'}))); // 给请求者反馈
    });
});
很快妥协 2022-09-12 02:54:43

php的话,选择定时任务只能用crontab,这样最短的轮训时间是1秒
如果想要1秒以内,就得另寻他法了。

汹涌人海 2022-09-12 02:54:43

可以用队列哦 然后后台用个进程处理就行了 swoole等都可以做后台进程

温柔女人霸气范 2022-09-12 02:54:42

有些个回答的方法并不太好,不用为好,小心为妙。

1.如果不一定非要php解决,那么采用linux的crontab
2.如果要用php解决,那么使用workerman( 这么简单一个需求,我就不让你用swoole了,太折腾 )
3.如果要用php解决,而且非要自己撸,请扩展如下简单粗暴的代码:

<?php
pcntl_signal(SIGALRM,function(){
  // do something, such as Calculate 30 day ...
  echo 'coming'.PHP_EOL;
});
pcntl_alarm(1);
while(true){
  pcntl_signal_dispatch();
  pcntl_alarm(1);
}

不用看了,我的回答的最全面最好使的

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文