Я пытаюсь сделать инструмент поиска файлов php, который использует диапазон дат, полученных из формы.
У меня есть каталоги, которые имеют следующий шаблон. Есть тысячи файлов, но это только пример.
ежедневная папка
chl-2009-05-08-121000.L2_LAC.x.png
chl-2009-05-09-111500.L2_LAC.x.png
chl-2009-05-09-112000.L2_LAC.x.png etc
еженедельная папка
lst-2014-W36.png
lst-2014-W37.png
lst-2014-W39.png etc
Форма имеет поле параметра, которое получит chl, lst и другие. Другие поля взяты из поля ввода даты, недели и т. Д.
Так что я хочу достичь, например, найти все файлы с именами файлов в диапазоне от 2002-04-14
а также 2003-05-25
, У меня есть переменная, которая предоставляет дату.
То, что я делал до сих пор, перечисляет только файлы, которые точно соответствуют предоставленным значениям с подстановочными знаками, но я не смог получить все файлы в пределах диапазонов дат. Я попытался для ежедневной папки.
$a = glob($datadir."{". $_GET['parameter'] .'-'. $_GET["date"]. "*,". $_GET['parameter'] .'-'. $_GET["date2"]. "*}" , GLOB_BRACE);
foreach($a as $image)
{
echo "<a href='".$image."'>" . basename($image) . "</a><br />";
}
Причина, по которой я использовал здесь символы подстановки, состоит в том, чтобы избежать проверки значений, подобных этим 112000.L2_LAC.x.png.
Спасибо!
Хитрость заключается в преобразовании ваших имен файлов и полей $ _POST в фактические даты, а затем в сравнение. Слишком проблематично рассматривать их как числа или строки & регулярные выражения.
Этот код заботится о chl
случай и lst
дело. Вы можете использовать ту же технику, чтобы обратиться к другим. Имейте в виду, что $user_start_date
а также $user_end_date
даты PHP Не струны.
Внизу я жестко запрограммировал некоторые даты начала и окончания. Очевидно, вы бы вместо этого использовали ваши значения $ _GET [‘date’] и $ _GET [‘date2’]. Документы PHP для DateTime :: createFromFormat () содержит информацию о том, как преобразовать строки различного формата в даты.
function filesInRange($datadir, $parameter, $user_start_date, $user_end_date) {
$all_files = array();
$good_files = array();
// first create an array of all the filenames, to keep I/O to a minimum
foreach (new DirectoryIterator($datadir) as $fileInfo) {
if ( $fileInfo->isFile() ) {
$all_files[] = $fileInfo->getFileName();
}
}
switch ($parameter) {
case 'chl':
foreach ($all_files as $filename) {
// we only operate on filenames that start with "chl". we skip others
if ( strpos($filename, $parameter) === 0 ) {
$pattern = '/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})-(?<hour>\d{2})(?<minute>\d{2})(?<second>\d{2})/';
preg_match($pattern, $filename, $matches);
$filedate = DateTime::createFromFormat('Y-m-j-His',$matches[0]);
// check range
if ($filedate >= $user_start_date && $filedate <= $user_end_date) {
$good_files[ $filedate->getTimestamp() ] = $filename;
}
}
}
break;
case 'lst':
foreach ($all_files as $filename) {
if ( strpos($filename, $parameter) === 0 ) {
$pattern = '/(?<year>\d{4})-W(?<week>\d{1,2})/';
preg_match($pattern, $filename, $matches);
// start on Jan 1 and keep adding days until we reach our desired week
$file_start_date = DateTime::createFromFormat('Y-m-d G:i:s',$matches['year'].'-01-01 00:00:00');
while ( $file_start_date->format('W') < $matches['week'] ) {
$file_start_date->modify('+1 day');
}
// add one week to get the end date
// the start day starts on the very first second of the day (00:00:00)
// the end date ends on the last second (23:59:59)
$file_end_date = clone $file_start_date;
$file_end_date->modify('+8 day');
$file_end_date->modify('-1 second');
// check range
if ($file_start_date >= $user_start_date && $file_end_date <= $user_end_date) {
$good_files[ $file_start_date->getTimestamp() ] = $filename;
}
}
}
break;
case 'some_other_format':
// handle other formats
break;
}
return $good_files;
}
$start = DateTime::createFromFormat('Y-m-j-His','2013-08-01-121000');
$end = DateTime::createFromFormat('Y-m-j-His','2015-09-15-121000');
$result1 = filesInRange($datadir, 'lst', $start, $end );
var_dump($result1);
Наконец работает диапазон поиска по всем форматам даты.
Этот код ниже взят из оригинального поста sean9999. Это работает для даты (ГГГГ-ММ-ДД), месяца (ГГГГ-ММ) и сезонного = ежемесячно (ГГГГ-январь).
function filesInRange($datadir, $timeper1, $timeper2, $format, $patternval) {
$matches=array();
$good_files = array();
$start = DateTime::createFromFormat( $format,$timeper1);
$end = DateTime::createFromFormat( $format,$timeper2);
$matches=array();
foreach (new DirectoryIterator($datadir) as $fileInfo) {
if ( !$fileInfo->isDot() && $fileInfo->isFile() ) {
// create a date by parsing the file name
//$pattern = $patternval ;
preg_match($patternval, $fileInfo->getFileName(), $matches);
if ($matches) {
$filedate = DateTime::createFromFormat($format, $matches[0]);
}// determine if it's between start and end date
if ($filedate >= $start && $filedate <= $end) {
$good_files[] = $datadir.$fileInfo->getFileName();
}
}
}
asort($good_files);
return $good_files;
}
Для вызова функции для ежедневных файлов.
$allfiles=filesInRange( "data/". $_GET["parameter"] . "/daily/", $_GET['date'], $_GET['date2'], 'Y-m-j', '/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/');
К сожалению, DateTime::createFromFormat
не поддерживает формат недели, как 2001W52
или же 2001-W52
, Таким образом, мне пришлось искать другой путь. Так что с незначительными изменениями я использовал date()
функция. Вот код для еженедельного поиска файлов.
function filesInRangeweek($datadir, $timeper1, $timeper2, $format, $patternval) {
$matches=array();
$good_files = array();
$start = date($format, strtotime($timeper1));
$end = date($format, strtotime($timeper2));
$matches=array();
foreach (new DirectoryIterator($datadir) as $fileInfo) {
if ( !$fileInfo->isDot() && $fileInfo->isFile() ) {
// create a date by parsing the file name
//$pattern = $patternval ;
preg_match($patternval, $fileInfo->getFileName(), $matches);
if ($matches) {
//echo $matches[0];
$filedate =date($format, strtotime($matches[0]));
}// determine if it's between start and end date
if ($filedate >= $start && $filedate <= $end) {
$good_files[] = $datadir.$fileInfo->getFileName();
}
}
}
asort($good_files);
return $good_files;
}
Вызвать функцию;
$result=filesInRangeweek( "data/lst/weekly/", '2013-W35', '2013-W45',"oW", '/(?<year>\d{4})-W(?<week>\d{2})/');