Jaki jest najlepszy sposób sprawdzania poprawności wpisu crontab w PHP? Czy powinienem używać wyrażeń regularnych lub biblioteki zewnętrznej? Mam skrypt PHP, który dodaje/usuwa wpisy z pliku crontab, ale chce mieć jakiś sposób sprawdzenia, czy przedział czasu jest w ważnym formacie.Sprawdzanie poprawności wpisów Crontab za pomocą PHP
Odpowiedz
Hmmm, interesujący problem.
Jeśli naprawdę chcesz to sprawdzić, wyrażenie regularne nie będzie wystarczające, musisz przeanalizować wpis i sprawdzić poprawność każdego z bitów planowania. To dlatego, że każdy bit może być liczbą, łańcuchem miesiąca/dnia tygodnia, przedziałem (2-7), zestawem (3, 4, sobota), skrótem Vixie w stylu cron (60/5) lub dowolną kombinacją z powyższego - każde pojedyncze podejście do wyrażenia regularnego będzie bardzo owłosione, szybkie.
Używanie programu Vixie cron do sprawdzania poprawności jest niewystarczające, ponieważ w rzeczywistości nie sprawdza się w pełni! Mogę uzyskać crontab
, aby zaakceptować wszystkie rodzaje nielegalnych rzeczy.
Dave Taylor's Wicked Cool Shell Scripts (Google books link) ma skrypt sh, który przeprowadza częściową walidację, uznałem dyskusję za interesującą. Możesz również użyć lub dostosować kod.
Ja również okazało się linki do dwóch klas PHP, że nie to, co mówisz (których jakość Nie oceniany):
- http://www.phpclasses.org/browse/package/1189.html
- http://www.phpclasses.org/browse/package/1985.html
Innym podejściem (w zależności od to, co twoja aplikacja musi zrobić) może polegać na tym, że PHP skonstruuje program crontab programowo i wstawi go, więc wiesz, że jest zawsze ważny, zamiast próbować sprawdzać niezaufany ciąg. Następnie wystarczy utworzyć interfejs użytkownika "buduj wpis crontab", co może być proste, jeśli nie potrzebujesz naprawdę skomplikowanych kombinacji planowania.
Powinieneś być w stanie to zrobić dość łatwo z regex. W rzeczywistości nie byłbym zaskoczony, gdyby można było znaleźć istniejące wyrażenie w tym właśnie w Google. To jest niesprawdzone, ale może coś takiego:
/^((\*)|(\d+((-\d+)|(,\d+)+))\s+){5}/
Kto powiedział, że wyrazy regularne nie mogą tego zrobić?
Dzięki uprzejmości mojego pracodawcy, Salir.com, oto test PHPUnit, który dokonuje takiego sprawdzenia. Możesz modyfikować dystrybucję &. Będę wdzięczny, jeśli będziesz utrzymywał link do @authora & link do strony internetowej.
<?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".
')';
}
}
To jest świetne! W moim przypadku chcę zweryfikować pełną treść linii crontab po linii. Tak więc po prostu dodaję kilka sprawdzeń przed uruchomieniem powyższego rozwiązania, aby również zweryfikować puste wiersze, linie zaczynające się od komentarza #, i linie z przypisaniami zmiennych "ABC = DEF" – bksunday
Podziękowania dla Jordi Salvat i Alabart, którzy napisali świetne rozwiązanie.
Mam tylko zmodyfikowane istniejące rozwiązanie opublikowane przez Jordi Salvat i Alabart. Udało mi się to dobrze, ale chciałem wydobyć poszczególne części, przechwytując grupy. Dodałem nieprzechwytujące nawiasy, aby móc wyodrębnić poszczególne części rekordu crontab.Łatwo jest sprawdzić, które przechwytywania grupa używać podczas testowania wyjścia regex w: http://www.regexplanet.com/advanced/java/index.html
<?php
/**
* @author Jordi Salvat i Alabart - with thanks to <a href="www.salir.com">Salir.com</a>.
*/
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-6]'
);
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+" .
"|($replacements)\s+" .
')' .
'([^\\s]+)\\s+' .
'(.*)$';
}
Ten kod generuje regex:
^\s*($|#|\w+\s*=|(\*(?:\/\d+)?|(?:[0-5]?\d)(?:-(?:[0-5]?\d)(?:\/\d+)?)?(?:,(?:[0-5]?\d)(?:-(?:[0-5]?\d)(?:\/\d+)?)?)*)\s+(\*(?:\/\d+)?|(?:[01]?\d|2[0-3])(?:-(?:[01]?\d|2[0-3])(?:\/\d+)?)?(?:,(?:[01]?\d|2[0-3])(?:-(?:[01]?\d|2[0-3])(?:\/\d+)?)?)*)\s+(\*(?:\/\d+)?|(?:0?[1-9]|[12]\d|3[01])(?:-(?:0?[1-9]|[12]\d|3[01])(?:\/\d+)?)?(?:,(?:0?[1-9]|[12]\d|3[01])(?:-(?:0?[1-9]|[12]\d|3[01])(?:\/\d+)?)?)*)\s+(\*(?:\/\d+)?|(?:[1-9]|1[012])(?:-(?:[1-9]|1[012])(?:\/\d+)?)?(?:,(?:[1-9]|1[012])(?:-(?:[1-9]|1[012])(?:\/\d+)?)?)*|jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\s+(\*(?:\/\d+)?|(?:[0-6])(?:-(?:[0-6])(?:\/\d+)?)?(?:,(?:[0-6])(?:-(?:[0-6])(?:\/\d+)?)?)*|mon|tue|wed|thu|fri|sat|sun)\s+|(@reboot|@yearly|@annually|@monthly|@weekly|@daily|@midnight|@hourly)\s+)([^\s]+)\s+(.*)$
lub alternatywne Java do wygenerowania tego regex (bez @x rzeczy):
public static String buildRegex(){
// numbers intervals and regex
Map<String, String> numbers = new HashMap<String, String>();
numbers.put("min", "[0-5]?\\d");
numbers.put("hour", "[01]?\\d|2[0-3]");
numbers.put("day", "0?[1-9]|[12]\\d|3[01]");
numbers.put("month", "[1-9]|1[012]");
numbers.put("dow", "[0-6]");
Map<String, String> field_re = new HashMap<String, String>();
// expand regex to contain different time specifiers
for(String field : numbers.keySet()){
String number = numbers.get(field);
String range = "(?:"+number+")(?:-(?:"+number+")(?:\\/\\d+)?)?";
field_re.put(field, "\\*(?:\\/\\d+)?|"+range+"(?:,"+range+")*");
}
// add string specifiers
String monthRE = field_re.get("month");
monthRE = monthRE + "|jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec";
field_re.put("month", monthRE);
String dowRE = field_re.get("dow");
dowRE = dowRE + "|mon|tue|wed|thu|fri|sat|sun";
field_re.put("dow", dowRE);
StringBuilder fieldsReSB = new StringBuilder();
fieldsReSB.append("^\\s*(")
.append("$")
.append("|#")
.append("|\\w+\\s*=")
.append("|");
.append("(")
.append(field_re.get("min")).append(")\\s+(")
.append(field_re.get("hour")).append(")\\s+(")
.append(field_re.get("day")).append(")\\s+(")
.append(field_re.get("month")).append(")\\s+(")
.append(field_re.get("dow"))
.append(")")
.append("\\s+)")
.append("([^\\s]+)\\s+")
.append("(.*)$");
return fieldsReSB.toString();
}
Nie wiem, wygenerowane wyrażenie regularne nie będzie pasować nawet prostym '* * * * * '. Co mam zrobić źle? https://regex101.com/r/rO2wW9/2 – bentinata
Podziękowania dla Jordi Salvat i Alabart oraz ph4r05.
Mam małe zmodyfikowane istniejące rozwiązanie opublikowane na php. Perl alternatywa do generowania wyrażenia regularnego:
sub _BuildRegex {
my $number = {
'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-6]'
};
my $field_re = {};
foreach my $nmb (qw/min hour day month dow/) {
my $range = "(?:$number->{$nmb})(?:-(?:$number->{$nmb})(?:\\/\\d+)?)?";
$field_re->{$nmb} = "\\*(?:\\/\\d+)?|$range(?:,$range)*";
}
$field_re->{'month'} .='|[jJ]an|[fF]eb|[mM]ar|[aA]pr|[mM]ay|[jJ]un|[jJ]ul|[aA]ug|[sS]ep|[oO]ct|[nN]ov|[dD]ec';
$field_re->{'dow'} .= '|[mM]on|[tT]ue|[wW]ed|[tT]hu|[fF]ri|[sS]at|[sS]un';
my $ff = [];
push @$ff, $field_re->{$_} foreach (qw/min hour day month dow/);
my $fields_req = '(' . join(')\s+(', @$ff) . ')';
my $replacements = '@reboot|@yearly|@annually|@monthly|@weekly|@daily|@midnight|@hourly';
return '^\s*(' .
'$' .
'|#' .
'|\w+\s*=' .
"|$fields_req\\s+" .
"|($replacements)\\s+" .
')' .
'([^\\s]+)\\s+' .
'(.*)$';
}
pomocą wzoru: /^((?:[1-9]?\d|\*)\s*(?:(?:[\/-][1-9]?\d)|(?:,[1-9]?\d)+)?\s*){5}$/
w PHP:
<?php
$cron = "*/5 1-2 3 3,4,5 *";
$result = preg_match("/^((?:[1-9]?\d|\*)\s*(?:(?:[\/-][1-9]?\d)|(?:,[1-9]?\d)+)?\s*){5}$/", $cron, $matches);
print_r($matches);
Jest miły biblioteki PHP, które mogą być wykorzystywane do sprawdzania poprawności wypowiedzi Cron:
Aby zainstalować tę bibliotekę poprzez kompozytor:
composer require mtdowling/cron-expression
Aby sprawdzić, czy wyraz Cron jest ważny
$isValid = Cron\CronExpression::isValidExpression($expression);
- 1. Sprawdzanie poprawności za pomocą Caliburn.Micro
- 2. Sprawdzanie poprawności XML za pomocą LibXML
- 3. Sprawdzanie poprawności jquery za pomocą wywołania ajax
- 4. Sprawdzanie poprawności liczby całkowitej za pomocą JSR303
- 5. Python - Sprawdzanie poprawności za pomocą wielu schematów za pomocą lxml
- 6. PHP Sprawdzanie poprawności przesłania pliku
- 7. Sprawdzanie poprawności json w php
- 8. Sprawdzanie poprawności JQuery: Sprawdzanie poprawności ukrytych pól
- 9. Sprawdzanie poprawności sprawdzania poprawności Knockout sprawdzanie poprawności
- 10. Sprawdzanie poprawności logowania za pomocą Angular Js i JSP
- 11. Sprawdzanie poprawności HTML5 za pomocą Opery i Safari
- 12. Sprawdzanie poprawności XML za pomocą XSD w Visual Studio IDE
- 13. Sprawdzanie poprawności atrybutów danych za pomocą klasy Validator
- 14. Orientacja obrazu i sprawdzanie poprawności za pomocą Paperclip?
- 15. Sprawdzanie poprawności składni/struktury XML za pomocą node.js
- 16. Sprawdzanie poprawności wielu pól tekstowych za pomocą errorprovider
- 17. Jak zastąpić sprawdzanie poprawności za pomocą Rails + Devise
- 18. Sprawdzanie poprawności zasobów JAX-RS (Apache Wink) za pomocą JSR303?
- 19. Sprawdzanie poprawności wyrażenia logicznego za pomocą nawiasów w języku C#
- 20. Sprawdzanie poprawności wielu typów zawartości za pomocą spinacza i szyn
- 21. Sprawdzanie poprawności XML po stronie serwera za pomocą CXF Webservice
- 22. Sprawdzanie poprawności formularza HTML przeglądarki podczas przesyłania za pomocą javascript?
- 23. sprawdzanie poprawności kątowej 2 form za pomocą komponentów
- 24. Sprawdzanie poprawności wejścia za pomocą języka JavaScript przy użyciu javascript
- 25. HTML5 Sprawdzanie poprawności za pomocą Nu Html Checker
- 26. Jak ręcznie uruchomić sprawdzanie poprawności za pomocą jQuery validate?
- 27. Sprawdzanie poprawności podzbioru formularza za pomocą wtyczki jQuery Validate
- 28. Laravel 5.0 IN Walidacja. Sprawdzanie poprawności za pomocą wartości ENUM
- 29. Sprawdzanie poprawności okna dialogowego
- 30. Sprawdzanie poprawności XML w stosunku do podanego DTD w PHP
to nie pasuje '@ reboot',' @ daily', '2- 39/4' i kilka innych rozszerzeń Vixie – Jasen