Wil*_*lco 12 php regex validation cron crontab
使用PHP验证crontab条目的最佳方法是什么?我应该使用正则表达式还是外部库?我有一个PHP脚本,用于添加/删除crontab文件中的条目,但希望能够通过某种方式验证时间间隔部分是否为有效格式.
Jor*_*art 23
谁说正则表达式不能那样做?
由我的雇主Salir.com提供,这是一个PHPUnit测试,它进行了这样的验证.随意修改和分发.如果您保留@author通知并链接到网站,我将不胜感激.
<?php
/**
* @author Jordi Salvat i Alabart - with thanks to <a href="www.salir.com">Salir.com</a>.
*/
abstract class CrontabChecker extends PHPUnit_Framework_TestCase {
protected function assertFileIsValidUserCrontab($file) {
$f= @fopen($file, 'r', 1);
$this->assertTrue($f !== false, 'Crontab file must exist');
while (($line= fgets($f)) !== false) {
$this->assertLineIsValid($line);
}
}
protected function assertLineIsValid($line) {
$regexp= $this->buildRegexp();
$this->assertTrue(preg_match("/$regexp/", $line) !== 0);
}
private function buildRegexp() {
$numbers= array(
'min'=>'[0-5]?\d',
'hour'=>'[01]?\d|2[0-3]',
'day'=>'0?[1-9]|[12]\d|3[01]',
'month'=>'[1-9]|1[012]',
'dow'=>'[0-7]'
);
foreach($numbers as $field=>$number) {
$range= "($number)(-($number)(\/\d+)?)?";
$field_re[$field]= "\*(\/\d+)?|$range(,$range)*";
}
$field_re['month'].='|jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec';
$field_re['dow'].='|mon|tue|wed|thu|fri|sat|sun';
$fields_re= '('.join(')\s+(', $field_re).')';
$replacements= '@reboot|@yearly|@annually|@monthly|@weekly|@daily|@midnight|@hourly';
return '^\s*('.
'$'.
'|#'.
'|\w+\s*='.
"|$fields_re\s+\S".
"|($replacements)\s+\S".
')';
}
}
Run Code Online (Sandbox Code Playgroud)
嗯,有趣的问题.
如果您要真正验证它,正则表达式还不够,您必须实际解析该条目并验证每个调度位.这是因为每个位可以是一个数字,一周的月/天字符串,一个范围(2-7),一组(3,4,星期六),一个Vixie cron风格的快捷方式(60/5)或任何组合以上 - 任何单一的正则表达式方法都会变得非常毛茸茸,快速.
仅仅使用crontabVixie cron程序进行验证是不够的,因为它实际上并没有完全验证!我可以crontab接受各种非法的事情.
Dave Taylor的Wicked Cool Shell Scripts(谷歌图书链接)有一个sh脚本,可以进行部分验证,我发现讨论很有趣.您也可以使用或调整代码.
我还发现了两个PHP类的链接,它们按照你说的做(我的质量没有评估):
另一种方法(取决于您的应用程序需要做什么)可能是让PHP以编程方式构造crontab条目并插入它,因此您知道它始终有效,而不是尝试验证不受信任的字符串.然后你只需要创建一个"构建一个crontab条目"UI,如果你不需要非常复杂的调度组合,这可能很简单.