Is it possible to pass a range of values to the glob function in PHP?

Question

I have a big number of files within a directory and I want to search for specific files with PHP glob function. This is my code:

/* SAMPLE FILE NAME: PR330037JED10220161204.csv */
$dir        = 'Files/Payment/';
$prefix     = 'PR';
$vendorNo   = '330037';
$region     = 'JED';
$date       = '20161204';
$files      = glob($dir.$prefix.$vendorNo.$region."*".$date.".csv");

It works fine, but I would like to check if the date part matches a range of dates. How do I change the glob expression?


Show source
| function   | php   | file   | search   | glob   2016-12-10 09:12 3 Answers

Answers ( 3 )

  1. 2016-12-10 09:12

    loop through the date range. try following code

    $dir        = 'Files/Payment/';
    $prefix     = 'PR';
    $vendorNo   = '330037';
    $region     = 'JED';
    
    $begin = new DateTime( '2016-12-05' );
    $end = new DateTime( '2016-12-10' );
    
    for($i = $begin; $begin <= $end; $i->modify('+1 day')) {
        $date = $i->format("Ymd");
        $files = glob($dir.$prefix.$vendorNo.$region."*".$date.".csv");
    }
    
  2. 2016-12-10 09:12

    You can make use of the GLOB_BRACE FLAG that glob() supports.

    Example :

    <?php
    
    $dir        = 'Files/Payment/';
    $prefix     = 'PR';
    $vendorNo   = '330037';
    $region     = 'JED';
    $date       = '20161204';
    
    $d1 = new DateTime();
    $d2 = new DateTime('-1 day');
    $d3 = new DateTime('-1 week');
    // Add your dates here. or even better find a way to generate the below list in an automated way, according to your needs
    $daysList = $d1->format('Ymd').','.$d2->format('Ymd').','.$d3->format('Ymd');
    
    $pattern      = $dir.$prefix.$vendorNo.$region."*"."{".$daysList."}".".csv";
    
    $files      = glob($pattern, GLOB_BRACE);
    
  3. 2016-12-10 09:12

    glob() doesn't support ranges. The best you can do with glob is to list the dates using GLOB_BRACE option:

    $date = '{20161204,20161205,20161206}';
    $pattern  = sprintf('%s/%s%s%s*%s.csv',
      $dir, $prefix, $vendorNo, $region, $date);
    
    $files = glob($pattern, GLOB_BRACE);
    

    A more flexible way is to iterate the directory, parse the date from the filename, and check if it belongs to an interval of dates:

    $it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir));
    
    $date_from = 20161204;
    $date_to   = 20161206;
    
    $pattern  = '/^' . preg_quote($prefix . $vendorNo . $region, '/') .
      '.*(?P<date>\d{8})\.csv$/';
    
    $it->rewind();
    while ($it->valid()) {
      if (!$it->isDot()) {
        $path = $it->key();
        $basename = basename($path);
        if (preg_match($pattern, $basename, $matches) &&
          isset($matches['date']) &&
          $matches['date'] >= $date_from &&
          $matches['date'] <= $date_to)
        {
          echo $basename, PHP_EOL;
        }
      }
    
      $it->next();
    }
    
◀ Go back