Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/278.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
接收cron字符串并返回下一次运行时间戳的PHP函数_Php_Cron_Scheduled Tasks_Scheduling_Crontab - Fatal编程技术网

接收cron字符串并返回下一次运行时间戳的PHP函数

接收cron字符串并返回下一次运行时间戳的PHP函数,php,cron,scheduled-tasks,scheduling,crontab,Php,Cron,Scheduled Tasks,Scheduling,Crontab,我需要开发一个任务系统,它应该能够在不支持crontab的服务器上工作 我询问是否有任何现有代码可以接受cron字符串(例如“0,12 1*/2*”)并返回下一次计划运行的时间戳 如果找不到这样的代码,那么我应该如何开始呢?您可以使用这个类 它还将计算最后一次计划运行使用此函数: function parse_crontab($time, $crontab) {$time=explode(' ', date('i G j n w', strtotime($time)));

我需要开发一个任务系统,它应该能够在不支持crontab的服务器上工作

我询问是否有任何现有代码可以接受cron字符串(例如“0,12 1*/2*”)并返回下一次计划运行的时间戳

如果找不到这样的代码,那么我应该如何开始呢?

您可以使用这个类

它还将计算最后一次计划运行

使用此函数:

function parse_crontab($time, $crontab)
         {$time=explode(' ', date('i G j n w', strtotime($time)));
          $crontab=explode(' ', $crontab);
          foreach ($crontab as $k=>&$v)
                  {$time[$k]=intval($time[$k]);
                   $v=explode(',', $v);
                   foreach ($v as &$v1)
                           {$v1=preg_replace(array('/^\*$/', '/^\d+$/', '/^(\d+)\-(\d+)$/', '/^\*\/(\d+)$/'),
                                             array('true', $time[$k].'===\0', '(\1<='.$time[$k].' and '.$time[$k].'<=\2)', $time[$k].'%\1===0'),
                                             $v1
                                            );
                           }
                   $v='('.implode(' or ', $v).')';
                  }
          $crontab=implode(' and ', $crontab);
          return eval('return '.$crontab.';');
         }
var_export(parse_crontab('2011-05-04 02:08:03', '*/2,3-5,9 2 3-5 */2 *'));
var_export(parse_crontab('2011-05-04 02:08:03', '*/8 */2 */4 */5 *'));
函数解析\u crontab($time,$crontab)
{$time=explode(“”,date('i G j n w',strottime($time));
$crontab=explode(“”,$crontab);
foreach($crontab作为$k=>&$v)
{$time[$k]=intval($time[$k]);
$v=爆炸(“,”,$v);
foreach($v as和$v1)
{$v1=preg\u replace(数组('/^\*$/'、'/^\d+$/'、'/^(\d+)\-(\d+)$/'、'/^\*\/(\d+)$/'),

数组('true',$time[$k].===\0','(\1您可以尝试以下方法:使用PHP Cron表达式解析器库,在
parse_crontab
函数中使用PHP类:

function parse_crontab($time, $crontab)
         {$time=explode(' ', date('i G j n w', strtotime($time)));
          $crontab=explode(' ', $crontab);
          foreach ($crontab as $k=>&$v)
                  {$time[$k]=intval($time[$k]);
                   $v=explode(',', $v);
                   foreach ($v as &$v1)
                           {$v1=preg_replace(array('/^\*$/', '/^\d+$/', '/^(\d+)\-(\d+)$/', '/^\*\/(\d+)$/'),
                                             array('true', $time[$k].'===\0', '(\1<='.$time[$k].' and '.$time[$k].'<=\2)', $time[$k].'%\1===0'),
                                             $v1
                                            );
                           }
                   $v='('.implode(' or ', $v).')';
                  }
          $crontab=implode(' and ', $crontab);
          return eval('return '.$crontab.';');
         }
var_export(parse_crontab('2011-05-04 02:08:03', '*/2,3-5,9 2 3-5 */2 *'));
var_export(parse_crontab('2011-05-04 02:08:03', '*/8 */2 */4 */5 *'));
$time[$k]
替换为
intval($time[$k])
preg\u Replace
行中

正确比较两个
base10
数字。

我发现diyism有一个很好的答案,但发现了一个关键的错误

如果您输入一个cron时间,例如
0****
,它将在0分钟、8分钟、9分钟运行。代码给出一个条件
08==0
,返回true,因为PHP将以0开头的数字解释为八进制,而08和09不是有效的八进制数,因此它们被解释为0。更多信息请参见此处

这里是diyism代码的一个固定版本,并且有很好的注释

// Parse CRON frequency
function parse_crontab($time, $crontab) {
    // Get current minute, hour, day, month, weekday
    $time = explode(' ', date('i G j n w', strtotime($time)));
    // Split crontab by space
    $crontab = explode(' ', $crontab);
    // Foreach part of crontab
    foreach ($crontab as $k => &$v) {
        // Remove leading zeros to prevent octal comparison, but not if number is already 1 digit
        $time[$k] = preg_replace('/^0+(?=\d)/', '', $time[$k]);
        // 5,10,15 each treated as seperate parts
        $v = explode(',', $v);
        // Foreach part we now have
        foreach ($v as &$v1) {
            // Do preg_replace with regular expression to create evaluations from crontab
            $v1 = preg_replace(
                // Regex
                array(
                    // *
                    '/^\*$/',
                    // 5
                    '/^\d+$/',
                    // 5-10
                    '/^(\d+)\-(\d+)$/',
                    // */5
                    '/^\*\/(\d+)$/'
                ),
                // Evaluations
                // trim leading 0 to prevent octal comparison
                array(
                    // * is always true
                    'true',
                    // Check if it is currently that time, 
                    $time[$k] . '===\0',
                    // Find if more than or equal lowest and lower or equal than highest
                    '(\1<=' . $time[$k] . ' and ' . $time[$k] . '<=\2)',
                    // Use modulus to find if true
                    $time[$k] . '%\1===0'
                ),
                // Subject we are working with
                $v1
            );
        }
        // Join 5,10,15 with `or` conditional
        $v = '(' . implode(' or ', $v) . ')';
    }
    // Require each part is true with `and` conditional
    $crontab = implode(' and ', $crontab);
    // Evaluate total condition to find if true
    return eval('return ' . $crontab . ';');
}
//解析CRON频率
函数parse_crontab($time,$crontab){
//获取当前分钟、小时、天、月、工作日
$time=explode(“”,date('i G j n w',strottime($time));
//按空间拆分crontab
$crontab=explode(“”,$crontab);
//crontab的每个部分
foreach($crontab作为$k=>&$v){
//删除前导零以防止八进制比较,但若数字已经是1位,则不删除前导零
$time[$k]=preg_replace('/^0+(?=\d)/','','$time[$k]);
//5,10,15各作为单独的部件处理
$v=爆炸(“,”,$v);
//我们现在拥有的每一部分
foreach($v as和$v1){
//是否使用正则表达式替换preg_以从crontab创建计算
$v1=预更换(
//正则表达式
排列(
// *
'/^\*$/',
// 5
“/^\d+$/”,
// 5-10
“/^(\d+)\-(\d+)$/”,
// */5
“/^\*\/(\d+)$/”
),
//评价
//修剪前导0以防止八进制比较
排列(
//*总是正确的
“真的”,
//检查当前是否为该时间,
$time[$k]。==\0',
//查找是否大于或等于最低值和低于或等于最高值

“(\1很久以前,我编写了一个非常强大的PHP类,名为CalendarEvent:

它支持两种不同的模式语法。普通的cron无法处理某些复杂的模式,而默认的CalendarEvent语法可以处理您可能需要的任何调度模式。cron模式语法支持实际上是一种回退(前缀cron行带有
cron
和空格)


CalendarEvent主要是作为一个日历事件计算类编写的,刚好支持cron风格的“下一个触发器”机制。它实际上是为了计算多个月的整个日程安排,以便向用户显示日历(因此称为类名称)。我还将该类用作在日历平台之间转换事件的中间解决方案。这是一种罕见的情况-我更频繁地将其用于AddSchedule()/NextTrigger()类似cron的解决方案。

您可以使用流行的包PHP cron表达式解析器


这也是Laravel框架的内置部分)

另请看我使用PHP Parse cron类在两台服务器上运行子cron,我没有遇到任何问题>>您需要是注册用户并登录才能获取此文件。您能重新表述您的答案吗?这很难理解。是否有Parse_crontab函数可用?在哪里?如何?替换代码的目的是什么?是吗你建议修改
parse_crontab
函数?很棒的函数。这里有一个更标准的代码样式。我在你的代码中发现了一个错误。请查看我的答案以获得解释,并可以将其应用于你的答案。@Goose,我认为“$time[$k]=intval($time[$k])”是可以的。
echo intval(09)
给出了0,所以不幸的是你必须使用
$time[$k]=preg\u replace('/^0+(?=\d)/“,”$time[$k]);
这没有回答OP问题,它不会返回下一个运行时!我认为“$time[$k]=intval($time[$k])”没问题,我已经更新了我的答案,谢谢。@diyism echo intval(09)
给出0,因此不幸的是,您必须使用
$time[$k]=preg\u replace(“/^0+(?=\d)/”,“$time[$k]);
这应该被标记为正确答案…非常精确且紧凑的解决方案!