Tôi thấy chủ nghĩa tự chế có câu trả lời tuyệt vời nhưng đã tìm thấy một lỗi nghiêm trọng.
Nếu bạn nhập thời gian cron như 0 * * * *
, nó sẽ chạy ở 0 phút, 8, phút và phút thứ 9. Mã cho một điều kiện 08===0
, trả về true, vì PHP diễn giải các số bắt đầu bằng 0 là bát phân, và 08 và 09 không phải là số bát phân hợp lệ để chúng được hiểu là 0. Thông tin thêm tại đây.
How to prevent PHP from doing octal math in conditionals? (why does 08 === 0)
Đây là phiên bản cố định và được nhận xét tốt về mã của chủ nghĩa tự chế.
// 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 . ';');
}
http://stackoverflow.com/questions/321494/calculate-when-a-cron-job-will-be-executed-then-next-time/3453872#3453872 –