Cách tốt nhất để xác thực mục nhập crontab bằng PHP là gì? Tôi có nên sử dụng regex hay thư viện bên ngoài không? Tôi đã có một kịch bản PHP cho biết thêm/loại bỏ các mục từ một tập tin crontab, nhưng muốn có một số cách để xác minh rằng phần khoảng thời gian là ở định dạng hợp lệ.Xác thực các mục nhập Crontab bằng PHP
Trả lời
Hmmm, vấn đề thú vị.
Nếu bạn định thực sự xác thực, regex sẽ không đủ, bạn sẽ phải phân tích cú pháp mục nhập và xác thực từng bit lập lịch biểu. Đó là bởi vì mỗi bit có thể là một số, một tháng/ngày của chuỗi tuần, một phạm vi (2-7), một tập hợp (3, 4, Thứ Bảy), lối tắt theo kiểu cron kiểu Vixie (60/5) hoặc bất kỳ kết hợp nào ở trên - bất kỳ phương pháp regex đơn lẻ nào cũng sẽ rất nhanh, rất nhanh.
Chỉ cần sử dụng chương trình crontab
của Vixie cron để xác thực không đủ, bởi vì nó thực sự không xác thực hoàn toàn! Tôi có thể nhận được crontab
để chấp nhận tất cả những thứ bất hợp pháp.
Kịch bản Wicked Cool Shell của Dave Taylor (Google books link) có kịch bản lệnh sh thực hiện xác thực một phần, tôi đã tìm thấy cuộc thảo luận thú vị. Bạn cũng có thể sử dụng hoặc điều chỉnh mã.
Tôi cũng bật lên những liên kết tới hai lớp PHP mà những gì bạn nói (mà chất lượng Tôi đã không được đánh giá):
- http://www.phpclasses.org/browse/package/1189.html
- http://www.phpclasses.org/browse/package/1985.html
cách tiếp cận khác (tùy thuộc vào những gì ứng dụng của bạn cần làm) có thể là để PHP xây dựng mục nhập crontab một cách có lập trình và chèn nó, vì vậy bạn biết nó luôn hợp lệ, thay vì cố gắng xác thực một chuỗi không đáng tin cậy. Sau đó, bạn chỉ cần tạo một giao diện người dùng "xây dựng một mục nhập crontab", điều này có thể đơn giản nếu bạn không cần các kết hợp lập lịch biểu phức tạp.
Bạn có thể làm điều đó khá dễ dàng với regex. Trong thực tế, tôi sẽ không ngạc nhiên nếu bạn có thể tìm thấy một regex hiện có cho chỉ trên Google. Điều này chưa được kiểm tra, nhưng có lẽ một cái gì đó như:
/^((\*)|(\d+((-\d+)|(,\d+)+))\s+){5}/
Ai nói cụm từ thông dụng không thể làm điều đó?
Được phép của chủ nhân của tôi, Salir.com, đây là bài kiểm tra PHPUnit có xác thực như vậy. Vui lòng sửa đổi & phân phối. Tôi sẽ đánh giá cao nếu bạn giữ thông báo @author & liên kết tới trang web.
<?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".
')';
}
}
Điều này thật tuyệt! Trong trường hợp của tôi, tôi muốn xác nhận một dòng nội dung crontab đầy đủ theo dòng. Vì vậy, tôi chỉ cần thêm vài kiểm tra trước khi chạy giải pháp trên để xác thực dòng trống, dòng bắt đầu bằng chú thích # và dòng có gán biến "ABC = DEF" – bksunday
Nhờ Jordi Salvat i Alabart đã đăng giải pháp tuyệt vời.
Tôi chỉ sửa đổi giải pháp hiện có được đăng bởi Jordi Salvat i Alabart. Nó làm việc tốt cho tôi, nhưng tôi muốn trích xuất các phần cụ thể bằng cách thu thập các nhóm. Tôi đã thêm dấu ngoặc đơn không bắt để có thể trích xuất các phần cụ thể của bản ghi crontab.Nó rất dễ dàng để xem cái nào chụp nhóm để sử dụng khi bạn kiểm tra đầu ra regex tại địa chỉ: 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+' .
'(.*)$';
}
Mã này tạo ra 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+(.*)$
Hoặc Java thay thế để tạo ra regex này (mà không @X thứ):
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();
}
Tôi không biết, regex được tạo sẽ không khớp ngay cả đơn giản '* * * * * '. Tôi làm gì sai? https://regex101.com/r/rO2wW9/2 – bentinata
Nhờ Jordi Salvat i Alabart và ph4r05.
Tôi có giải pháp sửa đổi nhỏ hiện có được đăng trên php. Perl thay thế để tạo ra regex:
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+' .
'(.*)$';
}
Sử dụng các mô hình: /^((?:[1-9]?\d|\*)\s*(?:(?:[\/-][1-9]?\d)|(?:,[1-9]?\d)+)?\s*){5}$/
Trong 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);
Có một PHP thư viện đẹp mà có thể được sử dụng cho Cron xác nhận biểu:
Để cài đặt thư viện này qua nhà soạn nhạc:
composer require mtdowling/cron-expression
Để kiểm tra xem biểu Cron là hợp lệ
$isValid = Cron\CronExpression::isValidExpression($expression);
- 1. Thực hiện php với crontab
- 2. Xác thực SOAP bằng PHP
- 3. Cách xác thực regex bằng PHP
- 4. cách thực hiện đăng nhập php hoặc phiên xác thực
- 5. Crontab - Chạy trong thư mục
- 6. Có công cụ nào cho phép hiển thị các mục nhập crontab không?
- 7. Xác thực REST bằng PHP (CodeIgniter)
- 8. IIS yêu cầu đăng nhập bằng chứng xác thực
- 9. Xác thực API PHP và các phiên
- 10. Thực thi python Script trên Crontab
- 11. crontab php và đầu ra để đăng nhập kết quả tập tin
- 12. Theo dõi các lần đăng nhập bằng cookie PHP
- 13. Email php xác thực
- 14. Tìm kiếm cronjob bằng crontab -l
- 15. Hashing & Salting - Xác thực đăng nhập bằng cookie
- 16. Đăng nhập WordPress trong jQuery Popup - Cách xác thực đăng nhập bằng jQuery Ajax?
- 17. PHP và .htaccess giải pháp xác thực
- 18. Đăng nhập một lần bằng Xác thực Mẫu
- 19. Làm cách nào để xác định xem tập lệnh python được thực thi từ crontab?
- 20. php xác thực regex
- 21. Tôi có thể nhập html bằng php bằng cách nào?
- 22. Làm cách nào để xác thực Ngày MYSQL bằng PHP?
- 23. Boolean xác thực PHP bằng cách sử dụng filter_var
- 24. xác thực biểu mẫu bằng javascript đến php
- 25. PHP - hướng dẫn cronjob/crontab/cron tốt hoặc cuốn sách
- 26. Không thể nhập mô-đun Python MySQL khi chạy tập lệnh bằng crontab
- 27. Xác thực đối tượng PHP
- 28. Xác thực trong Redbean PHP
- 29. PHP Xác thực Playstation Network
- 30. PHP "Session_regenerate_id" và Xác thực người dùng
này không phù hợp với '@ reboot',' @ daily', '2- 39/4' và một số phần mở rộng khác của Vixie – Jasen